From 30433ce029bd092d87dfa288933e7fd9eeb895c1 Mon Sep 17 00:00:00 2001 From: Conrado Gouvea Date: Wed, 21 Jun 2023 05:22:45 -0300 Subject: [PATCH] expand docs (#371) * expand docs * Apply suggestions from code review Co-authored-by: Deirdre Connolly * address comments, reflow some paragraphs * tutorial mostly done also cleaned up README example for extracting snippets; changed tests for consitency * docs: add DKG; organize sections; remove stale docs * run gencode * Apply suggestions from code review Co-authored-by: Pili Guerra --------- Co-authored-by: Deirdre Connolly Co-authored-by: Pili Guerra --- .github/workflows/docs.yml | 13 +- README.md | 6 +- book/book.toml | 13 +- book/mdbook-admonish.css | 353 ++++++++++++++++ book/src/SUMMARY.md | 19 +- book/src/dev.md | 3 + book/src/dev/rfcs.md | 1 - book/src/dev/rfcs/0001-messages.md | 1 - book/src/frost.md | 92 +++++ book/src/index.md | 11 + book/src/terminology.md | 10 + book/src/tutorial.md | 242 +++++++++++ book/src/tutorial/dkg.md | 82 ++++ book/src/tutorial/dkg/dkg.png | Bin 0 -> 79764 bytes book/src/tutorial/signing.png | Bin 0 -> 94492 bytes book/src/tutorial/tkg.png | Bin 0 -> 61752 bytes book/src/user.md | 8 + frost-core/src/tests/ciphersuite_generic.rs | 58 +-- frost-ed25519/README.md | 62 ++- frost-ed25519/dkg.md | 43 +- frost-ed448/README.md | 62 ++- frost-ed448/dkg.md | 43 +- frost-p256/README.md | 62 ++- frost-p256/dkg.md | 43 +- frost-ristretto255/README.md | 62 ++- frost-ristretto255/dkg.md | 43 +- frost-secp256k1/README.md | 62 ++- frost-secp256k1/dkg.md | 43 +- rfcs/0001-messages.md | 431 -------------------- 29 files changed, 1193 insertions(+), 675 deletions(-) create mode 100644 book/mdbook-admonish.css delete mode 100644 book/src/dev/rfcs.md delete mode 100644 book/src/dev/rfcs/0001-messages.md create mode 100644 book/src/frost.md create mode 100644 book/src/index.md create mode 100644 book/src/tutorial.md create mode 100644 book/src/tutorial/dkg.md create mode 100644 book/src/tutorial/dkg/dkg.png create mode 100644 book/src/tutorial/signing.png create mode 100644 book/src/tutorial/tkg.png delete mode 100644 rfcs/0001-messages.md diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 823ca01a..6cbfe3ed 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,7 +10,7 @@ concurrency: on: workflow_dispatch: pull_request: - branches: + branches: - main paths: # doc source files @@ -20,9 +20,9 @@ on: # workflow definitions - '.github/workflows/docs.yml' push: - branches: + branches: - main - + env: RUST_LOG: info RUST_BACKTRACE: full @@ -62,14 +62,15 @@ jobs: mdbook-version: '0.4.18' # TODO: actions-mdbook does not yet have an option to install mdbook-mermaid https://github.com/peaceiris/actions-mdbook/issues/426 - - name: Install mdbook + - name: Install plugins run: | cargo install mdbook-mermaid - + cargo install mdbook-admonish + - name: Build FROST book run: | mdbook build book/ - + - name: Deploy FROST book to Firebase preview channel uses: FirebaseExtended/action-hosting-deploy@v0 if: ${{ github.event_name == 'pull_request' && github.actor != 'dependabot[bot]' }} diff --git a/README.md b/README.md index fa2be595..74966229 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# FROST (Flexible Round-Optimised Schnorr Threshold signatures) +# ZF FROST (Flexible Round-Optimised Schnorr Threshold signatures) Rust implementations of ['Two-Round Threshold Schnorr Signatures with FROST'](https://datatracker.ietf.org/doc/draft-irtf-cfrg-frost/). @@ -17,6 +17,10 @@ to compute a signature, and implements signing efficiency improvements described [Schnorr21](https://eprint.iacr.org/2021/1375.pdf). Single-round signing with FROST is not implemented here. +## Getting Started + +Refer to the [ZF FROST book](https://frost.zfnd.org/). + ## Status ⚠ The FROST specification is not yet finalized, and this codebase has not yet been audited or diff --git a/book/book.toml b/book/book.toml index 31f13849..b0e302a4 100644 --- a/book/book.toml +++ b/book/book.toml @@ -3,4 +3,15 @@ authors = ["Zcash Foundation "] language = "en" multilingual = false src = "src" -title = "The FROST Book" +title = "The ZF FROST Book" + +[preprocessor] + +[preprocessor.admonish] +command = "mdbook-admonish" +assets_version = "2.0.1" # do not edit: managed by `mdbook-admonish install` + +[output] + +[output.html] +additional-css = ["./mdbook-admonish.css"] diff --git a/book/mdbook-admonish.css b/book/mdbook-admonish.css new file mode 100644 index 00000000..244bc9ad --- /dev/null +++ b/book/mdbook-admonish.css @@ -0,0 +1,353 @@ +@charset "UTF-8"; +:root { + --md-admonition-icon--note: + url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--abstract: + url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--info: + url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--tip: + url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--success: + url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--question: + url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--warning: + url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--failure: + url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--danger: + url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--bug: + url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--example: + url("data:image/svg+xml;charset=utf-8,"); + --md-admonition-icon--quote: + url("data:image/svg+xml;charset=utf-8,"); + --md-details-icon: + url("data:image/svg+xml;charset=utf-8,"); +} + +:is(.admonition) { + display: flow-root; + margin: 1.5625em 0; + padding: 0 1.2rem; + color: var(--fg); + page-break-inside: avoid; + background-color: var(--bg); + border: 0 solid black; + border-inline-start-width: 0.4rem; + border-radius: 0.2rem; + box-shadow: 0 0.2rem 1rem rgba(0, 0, 0, 0.05), 0 0 0.1rem rgba(0, 0, 0, 0.1); +} +@media print { + :is(.admonition) { + box-shadow: none; + } +} +:is(.admonition) > * { + box-sizing: border-box; +} +:is(.admonition) :is(.admonition) { + margin-top: 1em; + margin-bottom: 1em; +} +:is(.admonition) > .tabbed-set:only-child { + margin-top: 0; +} +html :is(.admonition) > :last-child { + margin-bottom: 1.2rem; +} + +a.admonition-anchor-link { + display: none; + position: absolute; + left: -1.2rem; + padding-right: 1rem; +} +a.admonition-anchor-link:link, a.admonition-anchor-link:visited { + color: var(--fg); +} +a.admonition-anchor-link:link:hover, a.admonition-anchor-link:visited:hover { + text-decoration: none; +} +a.admonition-anchor-link::before { + content: "§"; +} + +:is(.admonition-title, summary) { + position: relative; + min-height: 4rem; + margin-block: 0; + margin-inline: -1.6rem -1.2rem; + padding-block: 0.8rem; + padding-inline: 4.4rem 1.2rem; + font-weight: 700; + background-color: rgba(68, 138, 255, 0.1); + display: flex; +} +:is(.admonition-title, summary) p { + margin: 0; +} +html :is(.admonition-title, summary):last-child { + margin-bottom: 0; +} +:is(.admonition-title, summary)::before { + position: absolute; + top: 0.625em; + inset-inline-start: 1.6rem; + width: 2rem; + height: 2rem; + background-color: #448aff; + mask-image: url('data:image/svg+xml;charset=utf-8,'); + -webkit-mask-image: url('data:image/svg+xml;charset=utf-8,'); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-size: contain; + content: ""; +} +:is(.admonition-title, summary):hover a.admonition-anchor-link { + display: initial; +} + +details.admonition > summary.admonition-title::after { + position: absolute; + top: 0.625em; + inset-inline-end: 1.6rem; + height: 2rem; + width: 2rem; + background-color: currentcolor; + mask-image: var(--md-details-icon); + -webkit-mask-image: var(--md-details-icon); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-size: contain; + content: ""; + transform: rotate(0deg); + transition: transform 0.25s; +} +details[open].admonition > summary.admonition-title::after { + transform: rotate(90deg); +} + +:is(.admonition):is(.note) { + border-color: #448aff; +} + +:is(.note) > :is(.admonition-title, summary) { + background-color: rgba(68, 138, 255, 0.1); +} +:is(.note) > :is(.admonition-title, summary)::before { + background-color: #448aff; + mask-image: var(--md-admonition-icon--note); + -webkit-mask-image: var(--md-admonition-icon--note); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.abstract, .summary, .tldr) { + border-color: #00b0ff; +} + +:is(.abstract, .summary, .tldr) > :is(.admonition-title, summary) { + background-color: rgba(0, 176, 255, 0.1); +} +:is(.abstract, .summary, .tldr) > :is(.admonition-title, summary)::before { + background-color: #00b0ff; + mask-image: var(--md-admonition-icon--abstract); + -webkit-mask-image: var(--md-admonition-icon--abstract); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.info, .todo) { + border-color: #00b8d4; +} + +:is(.info, .todo) > :is(.admonition-title, summary) { + background-color: rgba(0, 184, 212, 0.1); +} +:is(.info, .todo) > :is(.admonition-title, summary)::before { + background-color: #00b8d4; + mask-image: var(--md-admonition-icon--info); + -webkit-mask-image: var(--md-admonition-icon--info); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.tip, .hint, .important) { + border-color: #00bfa5; +} + +:is(.tip, .hint, .important) > :is(.admonition-title, summary) { + background-color: rgba(0, 191, 165, 0.1); +} +:is(.tip, .hint, .important) > :is(.admonition-title, summary)::before { + background-color: #00bfa5; + mask-image: var(--md-admonition-icon--tip); + -webkit-mask-image: var(--md-admonition-icon--tip); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.success, .check, .done) { + border-color: #00c853; +} + +:is(.success, .check, .done) > :is(.admonition-title, summary) { + background-color: rgba(0, 200, 83, 0.1); +} +:is(.success, .check, .done) > :is(.admonition-title, summary)::before { + background-color: #00c853; + mask-image: var(--md-admonition-icon--success); + -webkit-mask-image: var(--md-admonition-icon--success); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.question, .help, .faq) { + border-color: #64dd17; +} + +:is(.question, .help, .faq) > :is(.admonition-title, summary) { + background-color: rgba(100, 221, 23, 0.1); +} +:is(.question, .help, .faq) > :is(.admonition-title, summary)::before { + background-color: #64dd17; + mask-image: var(--md-admonition-icon--question); + -webkit-mask-image: var(--md-admonition-icon--question); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.warning, .caution, .attention) { + border-color: #ff9100; +} + +:is(.warning, .caution, .attention) > :is(.admonition-title, summary) { + background-color: rgba(255, 145, 0, 0.1); +} +:is(.warning, .caution, .attention) > :is(.admonition-title, summary)::before { + background-color: #ff9100; + mask-image: var(--md-admonition-icon--warning); + -webkit-mask-image: var(--md-admonition-icon--warning); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.failure, .fail, .missing) { + border-color: #ff5252; +} + +:is(.failure, .fail, .missing) > :is(.admonition-title, summary) { + background-color: rgba(255, 82, 82, 0.1); +} +:is(.failure, .fail, .missing) > :is(.admonition-title, summary)::before { + background-color: #ff5252; + mask-image: var(--md-admonition-icon--failure); + -webkit-mask-image: var(--md-admonition-icon--failure); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.danger, .error) { + border-color: #ff1744; +} + +:is(.danger, .error) > :is(.admonition-title, summary) { + background-color: rgba(255, 23, 68, 0.1); +} +:is(.danger, .error) > :is(.admonition-title, summary)::before { + background-color: #ff1744; + mask-image: var(--md-admonition-icon--danger); + -webkit-mask-image: var(--md-admonition-icon--danger); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.bug) { + border-color: #f50057; +} + +:is(.bug) > :is(.admonition-title, summary) { + background-color: rgba(245, 0, 87, 0.1); +} +:is(.bug) > :is(.admonition-title, summary)::before { + background-color: #f50057; + mask-image: var(--md-admonition-icon--bug); + -webkit-mask-image: var(--md-admonition-icon--bug); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.example) { + border-color: #7c4dff; +} + +:is(.example) > :is(.admonition-title, summary) { + background-color: rgba(124, 77, 255, 0.1); +} +:is(.example) > :is(.admonition-title, summary)::before { + background-color: #7c4dff; + mask-image: var(--md-admonition-icon--example); + -webkit-mask-image: var(--md-admonition-icon--example); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +:is(.admonition):is(.quote, .cite) { + border-color: #9e9e9e; +} + +:is(.quote, .cite) > :is(.admonition-title, summary) { + background-color: rgba(158, 158, 158, 0.1); +} +:is(.quote, .cite) > :is(.admonition-title, summary)::before { + background-color: #9e9e9e; + mask-image: var(--md-admonition-icon--quote); + -webkit-mask-image: var(--md-admonition-icon--quote); + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-size: contain; + -webkit-mask-repeat: no-repeat; +} + +.navy :is(.admonition) { + background-color: var(--sidebar-bg); +} + +.ayu :is(.admonition), .coal :is(.admonition) { + background-color: var(--theme-hover); +} + +.rust :is(.admonition) { + background-color: var(--sidebar-bg); + color: var(--sidebar-fg); +} +.rust .admonition-anchor-link:link, .rust .admonition-anchor-link:visited { + color: var(--sidebar-fg); +} diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index f64b0440..d7cead82 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -1,21 +1,10 @@ # Summary -[FROST](README.md) +[ZF FROST](index.md) +- [Understanding FROST](frost.md) +- [Tutorial](tutorial.md) + - [Distributed Key Generation](tutorial/dkg.md) - [User Documentation](user.md) - - [frost-core](user/frost-core.md) - - [frost-rerandomized](user/frost-rerandomized.md) - - [frost-ed25519](user/frost-ed25519.md) - - [DKG](user/frost-ed25519/dkg.md) - - [frost-ed448](user/frost-ed448.md) - - [DKG](user/frost-ed448/dkg.md) - - [frost-p256](user/frost-p256.md) - - [DKG](user/frost-p256/dkg.md) - - [frost-ristretto255](user/frost-ristretto255.md) - - [DKG](user/frost-ristretto255/dkg.md) - - [frost-secp256k1](user/frost-secp256k1.md) - - [DKG](user/frost-secp256k1/dkg.md) - [Terminology](terminology.md) - [Developer Documentation](dev.md) - - [FROST RFCs](dev/rfcs.md) - - [FROST messages](dev/rfcs/0001-messages.md ) - [List of Dependencies for Audit](dev/frost-dependencies-for-audit.md) diff --git a/book/src/dev.md b/book/src/dev.md index 4796167e..3edcfeb9 100644 --- a/book/src/dev.md +++ b/book/src/dev.md @@ -1 +1,4 @@ # Developer Documentation + +This section contains information only relevant to ZF FROST developers or +contributors. diff --git a/book/src/dev/rfcs.md b/book/src/dev/rfcs.md deleted file mode 100644 index d811484c..00000000 --- a/book/src/dev/rfcs.md +++ /dev/null @@ -1 +0,0 @@ -# FROST RFCs diff --git a/book/src/dev/rfcs/0001-messages.md b/book/src/dev/rfcs/0001-messages.md deleted file mode 100644 index e5748f1a..00000000 --- a/book/src/dev/rfcs/0001-messages.md +++ /dev/null @@ -1 +0,0 @@ -{{#include ../../../../rfcs/0001-messages.md}} \ No newline at end of file diff --git a/book/src/frost.md b/book/src/frost.md new file mode 100644 index 00000000..86632f1a --- /dev/null +++ b/book/src/frost.md @@ -0,0 +1,92 @@ +# Understanding FROST + +This explains the main concepts and flows of FROST in a generic manner. These +are important to understand how to use the library, but rest assured that the +[Tutorial](tutorial.md) will have more concrete information. + +FROST is a threshold signature scheme. It allows splitting a Schnorr signing key +into `n` shares for a threshold `t`, such that `t` (or more) participants can +together generate a signature that can be validated by the corresponding verifying +key. One important aspect is that the resulting signature is indistinguishable from a +non-threshold signature from the point of view of signature verifiers. + +```admonish note +FROST only supports Schnorr signatures. Therefore it can't produce +ECDSA signatures. +``` + +## Key Generation + +There are two options for generating FROST key shares. In both cases, after the +key generation procedure, each participant will get: + +- a **secret share**; +- a **verifying share** (which can be used by other participants to verify the + signature shares the participant produces); +- a **group verifying key**, which is the public key matching the private key that was + split into shares; it is used to verify the final signature generated with FROST. + +### Trusted Dealer Generation + +An existing key (which can be freshly generated) is split into shares. It's the +simplest approach, but it has the downside of requiring the entire key to exist +in memory at some point in time, which may not be desired in high security +applications. However, it is much simpler to set up. It requires an +[authenticated and confidential communication +channel](https://frost.zfnd.org/terminology.html#peer-to-peer-channel) to +distribute each share to their respective participants. + +[Learn how to do Trusted Dealer Generation with the ZF FROST library](tutorial.md#generating-key-shares-with-a-trusted-dealer). + +### Distribtuted Key Generation + +A two-round protocol after which each participant will have their share of the +secret, without the secret being ever present in its entirety in any +participant's memory. Its downside is that it requires a [broadcast +channel](https://frost.zfnd.org/terminology.html#broadcast-channel) as well as +an [authenticated and confidential communication +channel](https://frost.zfnd.org/terminology.html#peer-to-peer-channel) between +each pair of participants, which may be difficult to deploy in practice. + +[Learn how to do Distributed Key Generation with the ZF FROST +library](tutorial/dkg.md). + +## Signing + +Signing with FROST starts with a Coordinator (which can be one of the +share holders, or not) which selects the message to be signed and +the participants that will generate the signature. + +Each participant sends fresh nonce commitments to the Coordinator, which then +consolidates them and sends them to each participant. Each one will then produce +a signature share, which is sent to the Coordinator who finally aggregates them +and produces the final signature. + +```admonish note +If having a single coordinator is not desired, then all participants +can act as coordinators. Refer to the +[spec](https://github.com/cfrg/draft-irtf-cfrg-frost/blob/master/draft-irtf-cfrg-frost.md#removing-the-coordinator-role-no-coordinator) +for more information. +``` + +```admonish warning +ALL participants who are selected for generating the signature need +to produce their share, even if there are more than `t` of them. +For example, in 2-of-3 signing, if 3 participants are selected, +them all 3 must produce signature shares in order for the Coordinator +be able to produce the final signature. Of course, the Coordinator +is still free to start the process with only 2 participants if they wish. +``` + +## Verifying + +Signature verification is carried out as normal with single-party signatures, +along with the signed message and the group verifying key as inputs. + + +## Ciphersuites + +FROST is a generic protocol that works with any adequate prime-order group, +which in practice are constructed from elliptic curves. The spec specifies +five ciphersuites with the Ristretto255, Ed25519, Ed448, P-256 and secp256k1 +groups. It's possible (though not recommended) to use your own ciphersuite. diff --git a/book/src/index.md b/book/src/index.md new file mode 100644 index 00000000..66fad0a2 --- /dev/null +++ b/book/src/index.md @@ -0,0 +1,11 @@ +# The ZF FROST Book + +This is a guide-level reference for the [ZF FROST library](https://github.com/ZcashFoundation/frost/). + +## Getting Started + +If you're not familiar with FROST, first read [Understanding FROST](frost.md). + +Then read the [Tutorial](tutorial.md), and use the [Rust +docs](user.md) as +reference. \ No newline at end of file diff --git a/book/src/terminology.md b/book/src/terminology.md index d8517a0c..f0265d5a 100644 --- a/book/src/terminology.md +++ b/book/src/terminology.md @@ -16,6 +16,16 @@ Possible deployment options: - Posting commitments to an authenticated centralized server that is trusted to provide a single view to all participants (also known as 'public bulletin board') +### _Identifier_ + +An identifier is a non-zero scalar (i.e. a number in a range specific to the +ciphersuite) which identifies a specific party. There are no restrictions to +them other than being unique for each participant and being in the valid range. + +In the ZF FROST library, they are either automatically generated incrementally +during key generation or can be instantiated from a byte array using +[`Identifier::deserialize()`](https://docs.rs/frost-core/latest/frost_core/frost/struct.Identifier.html#method.deserialize). + ### _Peer to peer channel_ Peer-to-peer channels are authenticated, reliable, and unordered, per the diff --git a/book/src/tutorial.md b/book/src/tutorial.md new file mode 100644 index 00000000..e06d033c --- /dev/null +++ b/book/src/tutorial.md @@ -0,0 +1,242 @@ +# Tutorial + +The ZF FROST suite consists of multiple crates. `frost-core` contains +a generic implementation of the protocol, which can't be used directly +without a concrete instantiation. + +The ciphersuite crates (`frost-ristretto255`, `frost-ed25519`, `frost-ed448`, +`frost-p256`, and `frost-secp256k1`) provide ciphersuites to use with +`frost-core`, but also re-expose the `frost-core` functions without +generics. If you will only use a single ciphersuite, then we recommend +using those functions, and this tutorial will follow this approach. +If you need to support multiple ciphersuites then feel free to use +`frost-core` along with the ciphersuite types. + +This tutorial will use the `frost-ristretto255` crate, but changing +to another ciphersuite should be a matter of simply changing the import. + +## Including `frost-ristretto255` + +Add to your `Cargo.toml` file: + +``` +[dependencies] +frost-ristretto255 = "0.3.0" +``` + +## Handling errors + +Most crate functions mentioned below return `Result`s with +[`Error`](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/type.Error.html)s. +All errors should be considered fatal and should lead to aborting the key +generation or signing procedure. + +## Serializing structures + +FROST is a distributed protocol and thus it requires sending messages between +participants. However, the ZF FROST library does not handle communication nor +encoding, which is the application's responsibility. For this reason, all +structures that need to be transmitted have public fields allowing the +application to encode and decode them as it wishes. (Note that fields like +`Scalar` and `Element` do have standard encodings; only the serialization of the +structure itself and things like maps and lists need to be handled by the +application.) + +The ZF FROST library will also support `serde` in the future, which will make +this process simpler. + + +## Generating key shares with a trusted dealer + +The diagram below shows the trusted dealer key generation process. Dashed lines +represent data being sent through an [authenticated and confidential communication +channel](https://frost.zfnd.org/terminology.html#peer-to-peer-channel). + +![Diagram of Trusted Dealer Key Generation, illustrating what is explained in the text](tutorial/tkg.png) + +To generate the key shares, the dealer calls +[`generate_with_dealer()`](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/keys/fn.generate_with_dealer.html). +It returns a `HashMap` mapping the (automatically generated) `Identifier`s to +their respective `SecretShare`s, and a `PublicKeyPackage` which contains the +`VerifyingShare` for each participant and the group public key (`VerifyingKey`). + +```rust,no_run,noplayground +{{#include ../../frost-ristretto255/README.md:tkg_gen}} +``` + +Each `SecretShare` must then be sent via an [**authenticated** and +**confidential** channel +](https://frost.zfnd.org/terminology.html#peer-to-peer-channel) for each +participant, who must verify the package to obtain a `KeyPackage` which contains +their signing share, verifying share and group verifying key. This is done with +[`KeyPackage::try_from()`](https://docs.rs/frost-core/latest/frost_core/frost/keys/struct.KeyPackage.html#method.try_from): + +```rust,no_run,noplayground +{{#include ../../frost-ristretto255/README.md:tkg_verify}} +``` + +```admonish info +Currently there is no way to specify which identifiers to use. This will +likely be supported in the future. + +[More information on how to handle Identifiers](https://frost.zfnd.org/terminology.html#identifier). +``` + +```admonish danger +Which [**authenticated** and **confidential** channel](https://frost.zfnd.org/terminology.html#peer-to-peer-channel) +to use is up to the application. Some examples: + +- Manually require the dealer to sent the `SecretShare`s to the + partipants using some secure messenger such as Signal; +- Use a TLS connection, authenticating the server with a certificate + and the client with some user/password or another suitable authentication + mechanism; + +Refer to the [Terminology page](https://frost.zfnd.org/terminology.html#peer-to-peer-channel) +for more details. + +Failure of using a **confidential** channel may lead to the shares being +stolen and possibly allowing signature forgeries if a threshold number of +them are stolen. + +Failure of using an **authenticated** channel may lead to shares being +sent to the wrong person, possibly allowing unintended parties +to generate signatures. +``` + +```admonish danger +The `SecretPackage` contents must be stored securely. For example: + +- Make sure other users in the system can't read it; +- If possible, use the OS secure storage such that the package + contents can only be opened with the user's password or biometrics. +``` + +```admonish warning +The participants may wish to not fully trust the dealer. While **the dealer +has access to the original secret and can forge signatures +by simply using the secret to sign** (and this can't be +possibly avoided with this method; use Distributed Key Generation +if that's an issue), the dealer could also tamper with the `SecretShare`s +in a way that the participants will never be able to generate a valid +signature in the future (denial of service). Participants can detect +such tampering by comparing the `VerifiableSecretSharingCommitment` +values from their `SecretShare`s (either by some manual process, or +by using a [broadcast channel](https://frost.zfnd.org/terminology.html#broadcast-channel)) +to make sure they are all equal. +``` + +## Signing + +The diagram below shows the signing process. Dashed lines represent data being +sent through an [authenticated communication +channel](https://frost.zfnd.org/terminology.html#peer-to-peer-channel). + +![Diagram of Signing, illustrating what is explained in the text](tutorial/signing.png) + +### Coordinator, Round 1 + +To sign, the +[Coordinator](file:///home/conrado/zfnd/frost/book/book/frost.html#signing) must +select which participants are going to generate the signature, and must signal +to start the process. This needs to be implemented by users of the ZF FROST library and will depend on +the communication channel being used. + +### Participants, Round 1 + +Each selected participant will then generate the nonces (a `SigningNonces`) and +their commitments (a `SigningCommitments`) by calling +[`round1::commit()`](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/round1/fn.commit.html): + +```rust,no_run,noplayground +{{#include ../../frost-ristretto255/README.md:round1_commit}} +``` + +The `SigningNonces` must be kept by the participant to use in Round 2, while the +`SigningCommitments` must be sent to the Coordinator using an [authenticated +channel](https://frost.zfnd.org/terminology.html#broadcast-channel). + +### Coordinator, Round 2 + +The Coordinator will get all `SigningCommitments` from the participants and the +message to be signed, and then build a `SigningPackage` by calling +[`SigningPackage::new()`](https://docs.rs/frost-core/latest/frost_core/frost/struct.SigningPackage.html#method.new). + +```rust,no_run,noplayground +{{#include ../../frost-ristretto255/README.md:round2_package}} +``` + +The `SigningPackage` must then be sent to all the participants using an +[authenticated +channel](https://frost.zfnd.org/terminology.html#peer-to-peer-channel). (Of course, +if the message is confidential, then the channel must also be confidential.) + +```admonish warning +In all of the main FROST ciphersuites, the entire message must +be sent to participants. In some cases, where the message is too big, it may be +necessary to send a hash of the message instead. We strongly suggest creating a +specific ciphersuite for this, and not just sending the hash as if it were the +message. For reference, see [how RFC 8032 handles +"pre-hashing"](https://datatracker.ietf.org/doc/html/rfc8032). +``` + +### Participants, Round 2 + +Upon receiving the `SigningPackage`, each participant will then produce their +signature share using their `KeyPackage` from the key generation process and +their `SigningNonces` from Round 1, by calling +[`round2::sign()`](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/round2/fn.sign.html): + +```rust,no_run,noplayground +{{#include ../../frost-ristretto255/README.md:round2_sign}} +``` + +The resulting `SignatureShare` must then be sent back to the Coordinator using +an [authenticated +channel](https://frost.zfnd.org/terminology.html#peer-to-peer-channel). + +```admonish important +In most applications, it is important that the participant must be aware of what +they are signing. Thus the application should show the message to the +participant and obtain their consent to proceed before producing the signature +share. +``` + +### Coordinator, Aggregate + +Upon receiving the `SignatureShare`s from the participants, the Coordinator can +finally produce the final signature by calling +[`aggregate()`](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/fn.aggregate.html) +with the same `SigningPackage` sent to the participants and the +`PublicKeyPackage` from the key generation (which is used to validate each +`SignatureShare`). + +```rust,no_run,noplayground +{{#include ../../frost-ristretto255/README.md:aggregate}} +``` + +The returned signature, a `Signature`, will be a valid signature for the message +chosen in Round 2 for the group verifying key in the `PublicKeyPackage`. + +```admonish note +FROST supports identifiable abort: if a participant misbehaves and produces an +invalid signature share, then aggregation will fail and the returned error +will have the identifier of the misbehaving participant. (If multiple participants +misbehave, only the first one detected will be returned.) + +What should be done in that case is up to the application. The misbehaving participant +could be excluded from future signing sessions, for example. +``` + + +## Verifying signatures + +The Coordinator could verify the signature with: + +```rust,no_run,noplayground +{{#include ../../frost-ristretto255/README.md:verify}} +``` + +(There is no need for the Coordinator to verify the signature since that already +happens inside `aggregate()`. This just shows how the signature can be +verified.) diff --git a/book/src/tutorial/dkg.md b/book/src/tutorial/dkg.md new file mode 100644 index 00000000..3e8a8540 --- /dev/null +++ b/book/src/tutorial/dkg.md @@ -0,0 +1,82 @@ +# Distributed Key Generation + +The diagram below shows the distributed key generation process. Dashed lines +represent data being sent through an [authenticated and confidential +communication +channel](https://frost.zfnd.org/terminology.html#peer-to-peer-channel). Note +that the first dashed line requires a [**broadcast +channel**](https://frost.zfnd.org/terminology.html#broadcast-channel) + +![Diagram of Distribtuted Key Generation, illustrating what is explained in the text](dkg/dkg.png) + +## Part 1 + +To start the DKG, each participant calls +[`dkg::part1()`](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/keys/dkg/fn.part1.html) +passing its identifier, the desired threshold and total number of participants. +(Thus, they need to agree on those parameters via some mechanism which is up to +the application.) It returns a `round1::SecretPackage` and a `round1::Package`: + +```rust,no_run,noplayground +{{#include ../../../frost-ristretto255/dkg.md:dkg_import}} + +// create `participant_identifier` somehow + +{{#include ../../../frost-ristretto255/dkg.md:dkg_part1}} +``` + +The `round1::SecretPackage` must be kept in memory to use in the next round. The +`round1::Package` must be sent to all other participants using a [**broadcast +channel**](https://frost.zfnd.org/terminology.html#broadcast-channel) to ensure +that all participants receive the same value. + +```admonish danger +A [**broadcast +channel**](https://frost.zfnd.org/terminology.html#broadcast-channel) in this +context is not simply broadcasting the value to all participants. It requires +running a protocol to ensure that all participants have the same value or that +the protocol is aborted. Check the linked [Terminology +section](https://frost.zfnd.org/terminology.html#broadcast-channel) for more +details. + +**Failure in using a proper broadcast channel will make the key generation +insecure.** +``` + +## Part 2 + +Upon receiving the other participants' `round1::Package`s, each participant then +calls +[`dkg::part2()`](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/keys/dkg/fn.part2.html) +passing their own previously created `round1::SecretPackage` and the list of +received `round1::Packages`. It returns a `round2::SecretPackage` and a +`HashMap` mapping other participants's `Identifier`s to `round2::Package`s: + +```rust,no_run,noplayground +{{#include ../../../frost-ristretto255/dkg.md:dkg_part2}} +``` + +The `round2::SecretPackage` must be kept in memory for the next part; the +`round1::SecretPackage` is consumed and is not required anymore. + +The `round2::Package`s must be sent to their respective participants with the +given `Identifier`s, using an [authenticated and confidential communication +channel](https://frost.zfnd.org/terminology.html#peer-to-peer-channel). + +## Part 3 + +Finally, upon receiving the other participant's `round2::Package`, the DKG is +concluded by calling +[`dkg::part3()`](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/keys/dkg/fn.part3.html) +passing the same `round1::Package`s received in Part 2, the `round2::Package`s +just received, and the previously stored `round2::SecretPackage` for the +participant. It returns a `KeyPackage`, with the participant's secret share, +and a `PublicKeyPackage` containing the group verifying key: + +```rust,no_run,noplayground +{{#include ../../../frost-ristretto255/dkg.md:dkg_part3}} +``` + +```admonish note +All participants will generate the same `PublicKeyPackage`. +``` \ No newline at end of file diff --git a/book/src/tutorial/dkg/dkg.png b/book/src/tutorial/dkg/dkg.png new file mode 100644 index 0000000000000000000000000000000000000000..4fa2c0497321d1272c8baa594670245d7289f37b GIT binary patch literal 79764 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:s<||atpVWW5VXp|0y9UQQataY-a8L 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

@?}#v{;LIhpDaL6I?nJ3@)s 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

Ecv-~e9_)Z zL;TJVhRp~{v;SnBMa4uD_#i;D|6GLWE_H%cR@Y|vi5a>R3B*rWNU5OhQP5C2X=kxj zyQb2>V54ES#8H|oA#>kmh~durk21iK*sVhmfl!uxX%WD(@5ZbXsy5g*-2uKJ5u~J2 z&<6GY0dDLp@Sq54)s~&bNG*Q9GBB!jt~5v?F;7bVnHT!CCw^X84|OJ850TV@hzG{a z0S+HB*=sEG;zGKUY-_Gs+S8Y^{eV1GLbb<4y|xP7K}X%KkhN7|a@zgp|Zk|NM^XX-JSjKy=9Y9tx)=ZN){nOY=` zM*$~Lu7NlS2}z78Ymm8`J#FuL8~p^O+hqq`%tWPR0MoK`fqkezsxRp{ZhPT_W@&$UWnkc-bsoNVSW=rDriTk+}6L+7!f|^n~PZKAHL_>MtOI%v{X5YS898Pe52>Yit`GY_yz z0d;TdMp_k85bSlNoL1D8Xy#ioJ5`&EObQB$5x}A{3zoKSt5!5$EJc#H4i4_7M4I@o z;S8yjXCqYs!`Tfm{DeuBJHBM&!SoOiAxbJ&~P9HPa}%UNRq|s1qJ}%hwbC_#+^qQl?TlAp-5aA&pmQ>{Vz{Eb*V(2ErluG`Dm_#F~5T)CwTK8rm=SxvY624=2)?-d4!~Se5 z4u@@$&ok9Qp=*Qbw&@oq1)d>K5tzw#zYKGRj6~6*5b}x6YH|)wcz}XEdG~Z_k?`&K z2HSS;6;)&TPRDX<1)aBMNJ#!tAB=-nP@AP<=v4T*DUh(m_p3JqTk2FZ*??1z>k+{f zzMh_*IcBw2VcsW&#?bz4TM#BvS?z{KK4$_@cBRhA=c3Q^vc|o<8dWR2qzW7$bgrUZ z*x^hTlmj_DHKqCchDNd6wVxzcnT5i4$7|i2xP(Ule?Z|*p+66);lyrDNZbf#gZ>z3 zR5RST=zdH{nChaCuQL7-OCiv zo=Og}kV~b8Y)Qmf-DI;E;WjJidRZ@vNQu-K{x{°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 z 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 AI{*Lx literal 0 HcmV?d00001 diff --git a/book/src/tutorial/tkg.png b/book/src/tutorial/tkg.png new file mode 100644 index 0000000000000000000000000000000000000000..4b9fa2bd009889bda6256a1a2072a41921705d15 GIT binary patch literal 61752 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 CWetJ= literal 0 HcmV?d00001 diff --git a/book/src/user.md b/book/src/user.md index 3a51d9a2..30c1cc8b 100644 --- a/book/src/user.md +++ b/book/src/user.md @@ -1 +1,9 @@ # User Documentation + +- [frost-core](https://docs.rs/frost-core/) +- [frost-rerandomized](https://docs.rs/frost-rerandomized/) +- [frost-ed25519](https://docs.rs/frost-ristretto255/) +- [frost-ed448](https://docs.rs/frost-ed448/) +- [frost-p256](https://docs.rs/frost-p256/) +- [frost-ristretto255](https://docs.rs/frost-ristretto255/) +- [frost-secp256k1](https://docs.rs/frost-secp256k1/) diff --git a/frost-core/src/tests/ciphersuite_generic.rs b/frost-core/src/tests/ciphersuite_generic.rs index 114d4d9f..ba1f9ac7 100644 --- a/frost-core/src/tests/ciphersuite_generic.rs +++ b/frost-core/src/tests/ciphersuite_generic.rs @@ -81,10 +81,11 @@ fn check_sign( min_signers: u16, key_packages: HashMap, frost::keys::KeyPackage>, mut rng: R, - pubkeys: frost::keys::PublicKeyPackage, + pubkey_package: frost::keys::PublicKeyPackage, ) -> (Vec, Signature, VerifyingKey) { - let mut nonces: HashMap, frost::round1::SigningNonces> = HashMap::new(); - let mut commitments: HashMap, frost::round1::SigningCommitments> = + let mut nonces_map: HashMap, frost::round1::SigningNonces> = + HashMap::new(); + let mut commitments_map: HashMap, frost::round1::SigningCommitments> = HashMap::new(); //////////////////////////////////////////////////////////////////////////// @@ -95,7 +96,7 @@ fn check_sign( let participant_identifier = participant_index.try_into().expect("should be nonzero"); // Generate one (1) nonce and one SigningCommitments instance for each // participant, up to _min_signers_. - let (nonce, commitment) = frost::round1::commit( + let (nonces, commitments) = frost::round1::commit( participant_identifier, key_packages .get(&participant_identifier) @@ -103,8 +104,8 @@ fn check_sign( .secret_share(), &mut rng, ); - nonces.insert(participant_identifier, nonce); - commitments.insert(participant_identifier, commitment); + nonces_map.insert(participant_identifier, nonces); + commitments_map.insert(participant_identifier, commitments); } // This is what the signature aggregator / coordinator needs to do: @@ -112,17 +113,17 @@ fn check_sign( // - take one (unused) commitment per signing participant let mut signature_shares = Vec::new(); let message = "message to sign".as_bytes(); - let comms = commitments.clone().into_values().collect(); + let comms = commitments_map.clone().into_values().collect(); let signing_package = frost::SigningPackage::new(comms, message.to_vec()); //////////////////////////////////////////////////////////////////////////// // Round 2: each participant generates their signature share //////////////////////////////////////////////////////////////////////////// - for participant_identifier in nonces.keys() { + for participant_identifier in nonces_map.keys() { let key_package = key_packages.get(participant_identifier).unwrap(); - let nonces_to_use = &nonces.get(participant_identifier).unwrap(); + let nonces_to_use = &nonces_map.get(participant_identifier).unwrap(); // Each participant generates their signature share. let signature_share = @@ -136,22 +137,20 @@ fn check_sign( //////////////////////////////////////////////////////////////////////////// // Aggregate (also verifies the signature shares) - let group_signature_res = frost::aggregate(&signing_package, &signature_shares[..], &pubkeys); - - assert!(group_signature_res.is_ok()); - - let group_signature = group_signature_res.unwrap(); + let group_signature = + frost::aggregate(&signing_package, &signature_shares[..], &pubkey_package).unwrap(); // Check that the threshold signature can be verified by the group public // key (the verification key). - assert!(pubkeys + let is_signature_valid = pubkey_package .group_public .verify(message, &group_signature) - .is_ok()); + .is_ok(); + assert!(is_signature_valid); // Check that the threshold signature can be verified by the group public // key (the verification key) from KeyPackage.group_public - for (participant_identifier, _) in nonces.clone() { + for (participant_identifier, _) in nonces_map.clone() { let key_package = key_packages.get(&participant_identifier).unwrap(); assert!(key_package @@ -160,7 +159,11 @@ fn check_sign( .is_ok()); } - (message.to_owned(), group_signature, pubkeys.group_public) + ( + message.to_owned(), + group_signature, + pubkey_package.group_public, + ) } /// Test FROST signing with trusted dealer with a Ciphersuite. @@ -197,13 +200,13 @@ where // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (secret_package, round1_package) = + let (round1_secret_package, round1_package) = frost::keys::dkg::part1(participant_identifier, max_signers, min_signers, &mut rng) .unwrap(); // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. - round1_secret_packages.insert(participant_identifier, secret_package); + round1_secret_packages.insert(participant_identifier, round1_secret_package); // "Send" the round 1 package to all other participants. In this // test this is simulated using a HashMap; in practice this will be @@ -240,15 +243,12 @@ where // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (round2_secret_package, round2_packages) = frost::keys::dkg::part2( - round1_secret_packages - .remove(&participant_identifier) - .unwrap(), - received_round1_packages - .get(&participant_identifier) - .unwrap(), - ) - .expect("should work"); + let round1_secret_package = round1_secret_packages + .remove(&participant_identifier) + .unwrap(); + let round1_packages = &received_round1_packages[&participant_identifier]; + let (round2_secret_package, round2_packages) = + frost::keys::dkg::part2(round1_secret_package, round1_packages).expect("should work"); // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. diff --git a/frost-ed25519/README.md b/frost-ed25519/README.md index 870b8510..8ced05e4 100644 --- a/frost-ed25519/README.md +++ b/frost-ed25519/README.md @@ -9,6 +9,7 @@ scenario in a single thread and it abstracts away any communication between peer ```rust +# // ANCHOR: tkg_gen use frost_ed25519 as frost; use rand::thread_rng; use std::collections::HashMap; @@ -16,20 +17,23 @@ use std::collections::HashMap; let mut rng = thread_rng(); let max_signers = 5; let min_signers = 3; -let (shares, pubkeys) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?; +let (shares, pubkey_package) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?; +# // ANCHOR_END: tkg_gen // Verifies the secret shares from the dealer and store them in a HashMap. // In practice, the KeyPackages must be sent to its respective participants // through a confidential and authenticated channel. let mut key_packages: HashMap<_, _> = HashMap::new(); -for (k, v) in shares { - let key_package = frost::keys::KeyPackage::try_from(v)?; - key_packages.insert(k, key_package); +for (identifier, secret_share) in shares { + # // ANCHOR: tkg_verify + let key_package = frost::keys::KeyPackage::try_from(secret_share)?; + # // ANCHOR_END: tkg_verify + key_packages.insert(identifier, key_package); } -let mut nonces = HashMap::new(); -let mut commitments = HashMap::new(); +let mut nonces_map = HashMap::new(); +let mut commitments_map = HashMap::new(); //////////////////////////////////////////////////////////////////////////// // Round 1: generating nonces and signing commitments for each participant @@ -38,43 +42,51 @@ let mut commitments = HashMap::new(); // In practice, each iteration of this loop will be executed by its respective participant. for participant_index in 1..(min_signers as u16 + 1) { let participant_identifier = participant_index.try_into().expect("should be nonzero"); + let key_package = &key_packages[&participant_identifier]; // Generate one (1) nonce and one SigningCommitments instance for each // participant, up to _threshold_. - let (nonce, commitment) = frost::round1::commit( + # // ANCHOR: round1_commit + let (nonces, commitments) = frost::round1::commit( participant_identifier, - key_packages[&participant_identifier].secret_share(), + key_package.secret_share(), &mut rng, ); - // In practice, the nonces and commitment must be sent to the coordinator + # // ANCHOR_END: round1_commit + // In practice, the nonces must be kept by the participant to use in the + // next round, while the commitment must be sent to the coordinator // (or to every other participant if there is no coordinator) using // an authenticated channel. - nonces.insert(participant_identifier, nonce); - commitments.insert(participant_identifier, commitment); + nonces_map.insert(participant_identifier, nonces); + commitments_map.insert(participant_identifier, commitments); } // This is what the signature aggregator / coordinator needs to do: // - decide what message to sign // - take one (unused) commitment per signing participant let mut signature_shares = Vec::new(); +let commitments_received = commitments_map.clone().into_values().collect(); +# // ANCHOR: round2_package let message = "message to sign".as_bytes(); -let comms = commitments.clone().into_values().collect(); -// In practice, the SigningPackage must be sent to all participants -// involved in the current signing (at least min_signers participants), -// using an authenticate channel (and confidential if the message is secret). -let signing_package = frost::SigningPackage::new(comms, message.to_vec()); +# // In practice, the SigningPackage must be sent to all participants +# // involved in the current signing (at least min_signers participants), +# // using an authenticate channel (and confidential if the message is secret). +let signing_package = frost::SigningPackage::new(commitments_received, message.to_vec()); +# // ANCHOR_END: round2_package //////////////////////////////////////////////////////////////////////////// // Round 2: each participant generates their signature share //////////////////////////////////////////////////////////////////////////// // In practice, each iteration of this loop will be executed by its respective participant. -for participant_identifier in nonces.keys() { +for participant_identifier in nonces_map.keys() { let key_package = &key_packages[participant_identifier]; - let nonces_to_use = &nonces[participant_identifier]; + let nonces = &nonces_map[participant_identifier]; // Each participant generates their signature share. - let signature_share = frost::round2::sign(&signing_package, nonces_to_use, key_package)?; + # // ANCHOR: round2_sign + let signature_share = frost::round2::sign(&signing_package, nonces, key_package)?; + # // ANCHOR_END: round2_sign // In practice, the signature share must be sent to the Coordinator // using an authenticated channel. @@ -87,14 +99,20 @@ for participant_identifier in nonces.keys() { //////////////////////////////////////////////////////////////////////////// // Aggregate (also verifies the signature shares) -let group_signature = frost::aggregate(&signing_package, &signature_shares[..], &pubkeys)?; +# // ANCHOR: aggregate +let group_signature = frost::aggregate(&signing_package, &signature_shares[..], &pubkey_package)?; +# // ANCHOR_END: aggregate + // Check that the threshold signature can be verified by the group public // key (the verification key). -assert!(pubkeys +# // ANCHOR: verify +let is_signature_valid = pubkey_package .group_public .verify(message, &group_signature) - .is_ok()); + .is_ok(); +# // ANCHOR_END: verify +assert!(is_signature_valid); # Ok::<(), frost::Error>(()) ``` diff --git a/frost-ed25519/dkg.md b/frost-ed25519/dkg.md index 3bb952a7..a0cf95d9 100644 --- a/frost-ed25519/dkg.md +++ b/frost-ed25519/dkg.md @@ -25,6 +25,7 @@ they can proceed to sign messages with FROST. ## Example ```rust +# // ANCHOR: dkg_import use rand::thread_rng; use std::collections::HashMap; @@ -32,13 +33,14 @@ use frost_ed25519 as frost; let mut rng = thread_rng(); +let max_signers = 5; +let min_signers = 3; +# // ANCHOR_END: dkg_import + //////////////////////////////////////////////////////////////////////////// // Key generation, Round 1 //////////////////////////////////////////////////////////////////////////// -let max_signers = 5; -let min_signers = 3; - // Keep track of each participant's round 1 secret package. // In practice each participant will keep its copy; no one // will have all the participant's packages. @@ -53,16 +55,18 @@ let mut received_round1_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (secret_package, round1_package) = frost::keys::dkg::part1( + # // ANCHOR: dkg_part1 + let (round1_secret_package, round1_package) = frost::keys::dkg::part1( participant_identifier, max_signers, min_signers, &mut rng, )?; + # // ANCHOR_END: dkg_part1 // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. - round1_secret_packages.insert(participant_identifier, secret_package); + round1_secret_packages.insert(participant_identifier, round1_secret_package); // "Send" the round 1 package to all other participants. In this // test this is simulated using a HashMap; in practice this will be @@ -99,12 +103,14 @@ let mut received_round2_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (round2_secret_package, round2_packages) = frost::keys::dkg::part2( - round1_secret_packages - .remove(&participant_identifier) - .unwrap(), - &received_round1_packages[&participant_identifier], - )?; + let round1_secret_package = round1_secret_packages + .remove(&participant_identifier) + .unwrap(); + let round1_packages = &received_round1_packages[&participant_identifier]; + # // ANCHOR: dkg_part2 + let (round2_secret_package, round2_packages) = + frost::keys::dkg::part2(round1_secret_package, round1_packages)?; + # // ANCHOR_END: dkg_part2 // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. @@ -142,13 +148,18 @@ let mut pubkey_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (key_package, pubkey_package_for_participant) = frost::keys::dkg::part3( - &round2_secret_packages[&participant_identifier], - &received_round1_packages[&participant_identifier], - &received_round2_packages[&participant_identifier], + let round2_secret_package = &round2_secret_packages[&participant_identifier]; + let round1_packages = &received_round1_packages[&participant_identifier]; + let round2_packages = &received_round2_packages[&participant_identifier]; + # // ANCHOR: dkg_part3 + let (key_package, pubkey_package) = frost::keys::dkg::part3( + round2_secret_package, + round1_packages, + round2_packages, )?; + # // ANCHOR_END: dkg_part3 key_packages.insert(participant_identifier, key_package); - pubkey_packages.insert(participant_identifier, pubkey_package_for_participant); + pubkey_packages.insert(participant_identifier, pubkey_package); } // With its own key package and the pubkey package, each participant can now proceed diff --git a/frost-ed448/README.md b/frost-ed448/README.md index d5463c21..fde4bfe9 100644 --- a/frost-ed448/README.md +++ b/frost-ed448/README.md @@ -9,6 +9,7 @@ scenario in a single thread and it abstracts away any communication between peer ```rust +# // ANCHOR: tkg_gen use frost_ed448 as frost; use rand::thread_rng; use std::collections::HashMap; @@ -16,20 +17,23 @@ use std::collections::HashMap; let mut rng = thread_rng(); let max_signers = 5; let min_signers = 3; -let (shares, pubkeys) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?; +let (shares, pubkey_package) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?; +# // ANCHOR_END: tkg_gen // Verifies the secret shares from the dealer and store them in a HashMap. // In practice, the KeyPackages must be sent to its respective participants // through a confidential and authenticated channel. let mut key_packages: HashMap<_, _> = HashMap::new(); -for (k, v) in shares { - let key_package = frost::keys::KeyPackage::try_from(v)?; - key_packages.insert(k, key_package); +for (identifier, secret_share) in shares { + # // ANCHOR: tkg_verify + let key_package = frost::keys::KeyPackage::try_from(secret_share)?; + # // ANCHOR_END: tkg_verify + key_packages.insert(identifier, key_package); } -let mut nonces = HashMap::new(); -let mut commitments = HashMap::new(); +let mut nonces_map = HashMap::new(); +let mut commitments_map = HashMap::new(); //////////////////////////////////////////////////////////////////////////// // Round 1: generating nonces and signing commitments for each participant @@ -38,43 +42,51 @@ let mut commitments = HashMap::new(); // In practice, each iteration of this loop will be executed by its respective participant. for participant_index in 1..(min_signers as u16 + 1) { let participant_identifier = participant_index.try_into().expect("should be nonzero"); + let key_package = &key_packages[&participant_identifier]; // Generate one (1) nonce and one SigningCommitments instance for each // participant, up to _threshold_. - let (nonce, commitment) = frost::round1::commit( + # // ANCHOR: round1_commit + let (nonces, commitments) = frost::round1::commit( participant_identifier, - key_packages[&participant_identifier].secret_share(), + key_package.secret_share(), &mut rng, ); - // In practice, the nonces and commitment must be sent to the coordinator + # // ANCHOR_END: round1_commit + // In practice, the nonces must be kept by the participant to use in the + // next round, while the commitment must be sent to the coordinator // (or to every other participant if there is no coordinator) using // an authenticated channel. - nonces.insert(participant_identifier, nonce); - commitments.insert(participant_identifier, commitment); + nonces_map.insert(participant_identifier, nonces); + commitments_map.insert(participant_identifier, commitments); } // This is what the signature aggregator / coordinator needs to do: // - decide what message to sign // - take one (unused) commitment per signing participant let mut signature_shares = Vec::new(); +let commitments_received = commitments_map.clone().into_values().collect(); +# // ANCHOR: round2_package let message = "message to sign".as_bytes(); -let comms = commitments.clone().into_values().collect(); -// In practice, the SigningPackage must be sent to all participants -// involved in the current signing (at least min_signers participants), -// using an authenticate channel (and confidential if the message is secret). -let signing_package = frost::SigningPackage::new(comms, message.to_vec()); +# // In practice, the SigningPackage must be sent to all participants +# // involved in the current signing (at least min_signers participants), +# // using an authenticate channel (and confidential if the message is secret). +let signing_package = frost::SigningPackage::new(commitments_received, message.to_vec()); +# // ANCHOR_END: round2_package //////////////////////////////////////////////////////////////////////////// // Round 2: each participant generates their signature share //////////////////////////////////////////////////////////////////////////// // In practice, each iteration of this loop will be executed by its respective participant. -for participant_identifier in nonces.keys() { +for participant_identifier in nonces_map.keys() { let key_package = &key_packages[participant_identifier]; - let nonces_to_use = &nonces[participant_identifier]; + let nonces = &nonces_map[participant_identifier]; // Each participant generates their signature share. - let signature_share = frost::round2::sign(&signing_package, nonces_to_use, key_package)?; + # // ANCHOR: round2_sign + let signature_share = frost::round2::sign(&signing_package, nonces, key_package)?; + # // ANCHOR_END: round2_sign // In practice, the signature share must be sent to the Coordinator // using an authenticated channel. @@ -87,14 +99,20 @@ for participant_identifier in nonces.keys() { //////////////////////////////////////////////////////////////////////////// // Aggregate (also verifies the signature shares) -let group_signature = frost::aggregate(&signing_package, &signature_shares[..], &pubkeys)?; +# // ANCHOR: aggregate +let group_signature = frost::aggregate(&signing_package, &signature_shares[..], &pubkey_package)?; +# // ANCHOR_END: aggregate + // Check that the threshold signature can be verified by the group public // key (the verification key). -assert!(pubkeys +# // ANCHOR: verify +let is_signature_valid = pubkey_package .group_public .verify(message, &group_signature) - .is_ok()); + .is_ok(); +# // ANCHOR_END: verify +assert!(is_signature_valid); # Ok::<(), frost::Error>(()) ``` diff --git a/frost-ed448/dkg.md b/frost-ed448/dkg.md index 3ee4f3f9..54212cfe 100644 --- a/frost-ed448/dkg.md +++ b/frost-ed448/dkg.md @@ -25,6 +25,7 @@ they can proceed to sign messages with FROST. ## Example ```rust +# // ANCHOR: dkg_import use rand::thread_rng; use std::collections::HashMap; @@ -32,13 +33,14 @@ use frost_ed448 as frost; let mut rng = thread_rng(); +let max_signers = 5; +let min_signers = 3; +# // ANCHOR_END: dkg_import + //////////////////////////////////////////////////////////////////////////// // Key generation, Round 1 //////////////////////////////////////////////////////////////////////////// -let max_signers = 5; -let min_signers = 3; - // Keep track of each participant's round 1 secret package. // In practice each participant will keep its copy; no one // will have all the participant's packages. @@ -53,16 +55,18 @@ let mut received_round1_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (secret_package, round1_package) = frost::keys::dkg::part1( + # // ANCHOR: dkg_part1 + let (round1_secret_package, round1_package) = frost::keys::dkg::part1( participant_identifier, max_signers, min_signers, &mut rng, )?; + # // ANCHOR_END: dkg_part1 // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. - round1_secret_packages.insert(participant_identifier, secret_package); + round1_secret_packages.insert(participant_identifier, round1_secret_package); // "Send" the round 1 package to all other participants. In this // test this is simulated using a HashMap; in practice this will be @@ -99,12 +103,14 @@ let mut received_round2_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (round2_secret_package, round2_packages) = frost::keys::dkg::part2( - round1_secret_packages - .remove(&participant_identifier) - .unwrap(), - &received_round1_packages[&participant_identifier], - )?; + let round1_secret_package = round1_secret_packages + .remove(&participant_identifier) + .unwrap(); + let round1_packages = &received_round1_packages[&participant_identifier]; + # // ANCHOR: dkg_part2 + let (round2_secret_package, round2_packages) = + frost::keys::dkg::part2(round1_secret_package, round1_packages)?; + # // ANCHOR_END: dkg_part2 // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. @@ -142,13 +148,18 @@ let mut pubkey_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (key_package, pubkey_package_for_participant) = frost::keys::dkg::part3( - &round2_secret_packages[&participant_identifier], - &received_round1_packages[&participant_identifier], - &received_round2_packages[&participant_identifier], + let round2_secret_package = &round2_secret_packages[&participant_identifier]; + let round1_packages = &received_round1_packages[&participant_identifier]; + let round2_packages = &received_round2_packages[&participant_identifier]; + # // ANCHOR: dkg_part3 + let (key_package, pubkey_package) = frost::keys::dkg::part3( + round2_secret_package, + round1_packages, + round2_packages, )?; + # // ANCHOR_END: dkg_part3 key_packages.insert(participant_identifier, key_package); - pubkey_packages.insert(participant_identifier, pubkey_package_for_participant); + pubkey_packages.insert(participant_identifier, pubkey_package); } // With its own key package and the pubkey package, each participant can now proceed diff --git a/frost-p256/README.md b/frost-p256/README.md index 81548c83..b33e4b84 100644 --- a/frost-p256/README.md +++ b/frost-p256/README.md @@ -9,6 +9,7 @@ scenario in a single thread and it abstracts away any communication between peer ```rust +# // ANCHOR: tkg_gen use frost_p256 as frost; use rand::thread_rng; use std::collections::HashMap; @@ -16,20 +17,23 @@ use std::collections::HashMap; let mut rng = thread_rng(); let max_signers = 5; let min_signers = 3; -let (shares, pubkeys) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?; +let (shares, pubkey_package) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?; +# // ANCHOR_END: tkg_gen // Verifies the secret shares from the dealer and store them in a HashMap. // In practice, the KeyPackages must be sent to its respective participants // through a confidential and authenticated channel. let mut key_packages: HashMap<_, _> = HashMap::new(); -for (k, v) in shares { - let key_package = frost::keys::KeyPackage::try_from(v)?; - key_packages.insert(k, key_package); +for (identifier, secret_share) in shares { + # // ANCHOR: tkg_verify + let key_package = frost::keys::KeyPackage::try_from(secret_share)?; + # // ANCHOR_END: tkg_verify + key_packages.insert(identifier, key_package); } -let mut nonces = HashMap::new(); -let mut commitments = HashMap::new(); +let mut nonces_map = HashMap::new(); +let mut commitments_map = HashMap::new(); //////////////////////////////////////////////////////////////////////////// // Round 1: generating nonces and signing commitments for each participant @@ -38,43 +42,51 @@ let mut commitments = HashMap::new(); // In practice, each iteration of this loop will be executed by its respective participant. for participant_index in 1..(min_signers as u16 + 1) { let participant_identifier = participant_index.try_into().expect("should be nonzero"); + let key_package = &key_packages[&participant_identifier]; // Generate one (1) nonce and one SigningCommitments instance for each // participant, up to _threshold_. - let (nonce, commitment) = frost::round1::commit( + # // ANCHOR: round1_commit + let (nonces, commitments) = frost::round1::commit( participant_identifier, - key_packages[&participant_identifier].secret_share(), + key_package.secret_share(), &mut rng, ); - // In practice, the nonces and commitment must be sent to the coordinator + # // ANCHOR_END: round1_commit + // In practice, the nonces must be kept by the participant to use in the + // next round, while the commitment must be sent to the coordinator // (or to every other participant if there is no coordinator) using // an authenticated channel. - nonces.insert(participant_identifier, nonce); - commitments.insert(participant_identifier, commitment); + nonces_map.insert(participant_identifier, nonces); + commitments_map.insert(participant_identifier, commitments); } // This is what the signature aggregator / coordinator needs to do: // - decide what message to sign // - take one (unused) commitment per signing participant let mut signature_shares = Vec::new(); +let commitments_received = commitments_map.clone().into_values().collect(); +# // ANCHOR: round2_package let message = "message to sign".as_bytes(); -let comms = commitments.clone().into_values().collect(); -// In practice, the SigningPackage must be sent to all participants -// involved in the current signing (at least min_signers participants), -// using an authenticate channel (and confidential if the message is secret). -let signing_package = frost::SigningPackage::new(comms, message.to_vec()); +# // In practice, the SigningPackage must be sent to all participants +# // involved in the current signing (at least min_signers participants), +# // using an authenticate channel (and confidential if the message is secret). +let signing_package = frost::SigningPackage::new(commitments_received, message.to_vec()); +# // ANCHOR_END: round2_package //////////////////////////////////////////////////////////////////////////// // Round 2: each participant generates their signature share //////////////////////////////////////////////////////////////////////////// // In practice, each iteration of this loop will be executed by its respective participant. -for participant_identifier in nonces.keys() { +for participant_identifier in nonces_map.keys() { let key_package = &key_packages[participant_identifier]; - let nonces_to_use = &nonces[participant_identifier]; + let nonces = &nonces_map[participant_identifier]; // Each participant generates their signature share. - let signature_share = frost::round2::sign(&signing_package, nonces_to_use, key_package)?; + # // ANCHOR: round2_sign + let signature_share = frost::round2::sign(&signing_package, nonces, key_package)?; + # // ANCHOR_END: round2_sign // In practice, the signature share must be sent to the Coordinator // using an authenticated channel. @@ -87,14 +99,20 @@ for participant_identifier in nonces.keys() { //////////////////////////////////////////////////////////////////////////// // Aggregate (also verifies the signature shares) -let group_signature = frost::aggregate(&signing_package, &signature_shares[..], &pubkeys)?; +# // ANCHOR: aggregate +let group_signature = frost::aggregate(&signing_package, &signature_shares[..], &pubkey_package)?; +# // ANCHOR_END: aggregate + // Check that the threshold signature can be verified by the group public // key (the verification key). -assert!(pubkeys +# // ANCHOR: verify +let is_signature_valid = pubkey_package .group_public .verify(message, &group_signature) - .is_ok()); + .is_ok(); +# // ANCHOR_END: verify +assert!(is_signature_valid); # Ok::<(), frost::Error>(()) ``` diff --git a/frost-p256/dkg.md b/frost-p256/dkg.md index ab515ed3..ff3b80f4 100644 --- a/frost-p256/dkg.md +++ b/frost-p256/dkg.md @@ -25,6 +25,7 @@ they can proceed to sign messages with FROST. ## Example ```rust +# // ANCHOR: dkg_import use rand::thread_rng; use std::collections::HashMap; @@ -32,13 +33,14 @@ use frost_p256 as frost; let mut rng = thread_rng(); +let max_signers = 5; +let min_signers = 3; +# // ANCHOR_END: dkg_import + //////////////////////////////////////////////////////////////////////////// // Key generation, Round 1 //////////////////////////////////////////////////////////////////////////// -let max_signers = 5; -let min_signers = 3; - // Keep track of each participant's round 1 secret package. // In practice each participant will keep its copy; no one // will have all the participant's packages. @@ -53,16 +55,18 @@ let mut received_round1_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (secret_package, round1_package) = frost::keys::dkg::part1( + # // ANCHOR: dkg_part1 + let (round1_secret_package, round1_package) = frost::keys::dkg::part1( participant_identifier, max_signers, min_signers, &mut rng, )?; + # // ANCHOR_END: dkg_part1 // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. - round1_secret_packages.insert(participant_identifier, secret_package); + round1_secret_packages.insert(participant_identifier, round1_secret_package); // "Send" the round 1 package to all other participants. In this // test this is simulated using a HashMap; in practice this will be @@ -99,12 +103,14 @@ let mut received_round2_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (round2_secret_package, round2_packages) = frost::keys::dkg::part2( - round1_secret_packages - .remove(&participant_identifier) - .unwrap(), - &received_round1_packages[&participant_identifier], - )?; + let round1_secret_package = round1_secret_packages + .remove(&participant_identifier) + .unwrap(); + let round1_packages = &received_round1_packages[&participant_identifier]; + # // ANCHOR: dkg_part2 + let (round2_secret_package, round2_packages) = + frost::keys::dkg::part2(round1_secret_package, round1_packages)?; + # // ANCHOR_END: dkg_part2 // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. @@ -142,13 +148,18 @@ let mut pubkey_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (key_package, pubkey_package_for_participant) = frost::keys::dkg::part3( - &round2_secret_packages[&participant_identifier], - &received_round1_packages[&participant_identifier], - &received_round2_packages[&participant_identifier], + let round2_secret_package = &round2_secret_packages[&participant_identifier]; + let round1_packages = &received_round1_packages[&participant_identifier]; + let round2_packages = &received_round2_packages[&participant_identifier]; + # // ANCHOR: dkg_part3 + let (key_package, pubkey_package) = frost::keys::dkg::part3( + round2_secret_package, + round1_packages, + round2_packages, )?; + # // ANCHOR_END: dkg_part3 key_packages.insert(participant_identifier, key_package); - pubkey_packages.insert(participant_identifier, pubkey_package_for_participant); + pubkey_packages.insert(participant_identifier, pubkey_package); } // With its own key package and the pubkey package, each participant can now proceed diff --git a/frost-ristretto255/README.md b/frost-ristretto255/README.md index a3ac17b9..c7d0625b 100644 --- a/frost-ristretto255/README.md +++ b/frost-ristretto255/README.md @@ -9,6 +9,7 @@ scenario in a single thread and it abstracts away any communication between peer ```rust +# // ANCHOR: tkg_gen use frost_ristretto255 as frost; use rand::thread_rng; use std::collections::HashMap; @@ -16,20 +17,23 @@ use std::collections::HashMap; let mut rng = thread_rng(); let max_signers = 5; let min_signers = 3; -let (shares, pubkeys) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?; +let (shares, pubkey_package) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?; +# // ANCHOR_END: tkg_gen // Verifies the secret shares from the dealer and store them in a HashMap. // In practice, the KeyPackages must be sent to its respective participants // through a confidential and authenticated channel. let mut key_packages: HashMap<_, _> = HashMap::new(); -for (k, v) in shares { - let key_package = frost::keys::KeyPackage::try_from(v)?; - key_packages.insert(k, key_package); +for (identifier, secret_share) in shares { + # // ANCHOR: tkg_verify + let key_package = frost::keys::KeyPackage::try_from(secret_share)?; + # // ANCHOR_END: tkg_verify + key_packages.insert(identifier, key_package); } -let mut nonces = HashMap::new(); -let mut commitments = HashMap::new(); +let mut nonces_map = HashMap::new(); +let mut commitments_map = HashMap::new(); //////////////////////////////////////////////////////////////////////////// // Round 1: generating nonces and signing commitments for each participant @@ -38,43 +42,51 @@ let mut commitments = HashMap::new(); // In practice, each iteration of this loop will be executed by its respective participant. for participant_index in 1..(min_signers as u16 + 1) { let participant_identifier = participant_index.try_into().expect("should be nonzero"); + let key_package = &key_packages[&participant_identifier]; // Generate one (1) nonce and one SigningCommitments instance for each // participant, up to _threshold_. - let (nonce, commitment) = frost::round1::commit( + # // ANCHOR: round1_commit + let (nonces, commitments) = frost::round1::commit( participant_identifier, - key_packages[&participant_identifier].secret_share(), + key_package.secret_share(), &mut rng, ); - // In practice, the nonces and commitment must be sent to the coordinator + # // ANCHOR_END: round1_commit + // In practice, the nonces must be kept by the participant to use in the + // next round, while the commitment must be sent to the coordinator // (or to every other participant if there is no coordinator) using // an authenticated channel. - nonces.insert(participant_identifier, nonce); - commitments.insert(participant_identifier, commitment); + nonces_map.insert(participant_identifier, nonces); + commitments_map.insert(participant_identifier, commitments); } // This is what the signature aggregator / coordinator needs to do: // - decide what message to sign // - take one (unused) commitment per signing participant let mut signature_shares = Vec::new(); +let commitments_received = commitments_map.clone().into_values().collect(); +# // ANCHOR: round2_package let message = "message to sign".as_bytes(); -let comms = commitments.clone().into_values().collect(); -// In practice, the SigningPackage must be sent to all participants -// involved in the current signing (at least min_signers participants), -// using an authenticate channel (and confidential if the message is secret). -let signing_package = frost::SigningPackage::new(comms, message.to_vec()); +# // In practice, the SigningPackage must be sent to all participants +# // involved in the current signing (at least min_signers participants), +# // using an authenticate channel (and confidential if the message is secret). +let signing_package = frost::SigningPackage::new(commitments_received, message.to_vec()); +# // ANCHOR_END: round2_package //////////////////////////////////////////////////////////////////////////// // Round 2: each participant generates their signature share //////////////////////////////////////////////////////////////////////////// // In practice, each iteration of this loop will be executed by its respective participant. -for participant_identifier in nonces.keys() { +for participant_identifier in nonces_map.keys() { let key_package = &key_packages[participant_identifier]; - let nonces_to_use = &nonces[participant_identifier]; + let nonces = &nonces_map[participant_identifier]; // Each participant generates their signature share. - let signature_share = frost::round2::sign(&signing_package, nonces_to_use, key_package)?; + # // ANCHOR: round2_sign + let signature_share = frost::round2::sign(&signing_package, nonces, key_package)?; + # // ANCHOR_END: round2_sign // In practice, the signature share must be sent to the Coordinator // using an authenticated channel. @@ -87,14 +99,20 @@ for participant_identifier in nonces.keys() { //////////////////////////////////////////////////////////////////////////// // Aggregate (also verifies the signature shares) -let group_signature = frost::aggregate(&signing_package, &signature_shares[..], &pubkeys)?; +# // ANCHOR: aggregate +let group_signature = frost::aggregate(&signing_package, &signature_shares[..], &pubkey_package)?; +# // ANCHOR_END: aggregate + // Check that the threshold signature can be verified by the group public // key (the verification key). -assert!(pubkeys +# // ANCHOR: verify +let is_signature_valid = pubkey_package .group_public .verify(message, &group_signature) - .is_ok()); + .is_ok(); +# // ANCHOR_END: verify +assert!(is_signature_valid); # Ok::<(), frost::Error>(()) ``` diff --git a/frost-ristretto255/dkg.md b/frost-ristretto255/dkg.md index c7de1c29..3aee3284 100644 --- a/frost-ristretto255/dkg.md +++ b/frost-ristretto255/dkg.md @@ -25,6 +25,7 @@ they can proceed to sign messages with FROST. ## Example ```rust +# // ANCHOR: dkg_import use rand::thread_rng; use std::collections::HashMap; @@ -32,13 +33,14 @@ use frost_ristretto255 as frost; let mut rng = thread_rng(); +let max_signers = 5; +let min_signers = 3; +# // ANCHOR_END: dkg_import + //////////////////////////////////////////////////////////////////////////// // Key generation, Round 1 //////////////////////////////////////////////////////////////////////////// -let max_signers = 5; -let min_signers = 3; - // Keep track of each participant's round 1 secret package. // In practice each participant will keep its copy; no one // will have all the participant's packages. @@ -53,16 +55,18 @@ let mut received_round1_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (secret_package, round1_package) = frost::keys::dkg::part1( + # // ANCHOR: dkg_part1 + let (round1_secret_package, round1_package) = frost::keys::dkg::part1( participant_identifier, max_signers, min_signers, &mut rng, )?; + # // ANCHOR_END: dkg_part1 // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. - round1_secret_packages.insert(participant_identifier, secret_package); + round1_secret_packages.insert(participant_identifier, round1_secret_package); // "Send" the round 1 package to all other participants. In this // test this is simulated using a HashMap; in practice this will be @@ -99,12 +103,14 @@ let mut received_round2_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (round2_secret_package, round2_packages) = frost::keys::dkg::part2( - round1_secret_packages - .remove(&participant_identifier) - .unwrap(), - &received_round1_packages[&participant_identifier], - )?; + let round1_secret_package = round1_secret_packages + .remove(&participant_identifier) + .unwrap(); + let round1_packages = &received_round1_packages[&participant_identifier]; + # // ANCHOR: dkg_part2 + let (round2_secret_package, round2_packages) = + frost::keys::dkg::part2(round1_secret_package, round1_packages)?; + # // ANCHOR_END: dkg_part2 // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. @@ -142,13 +148,18 @@ let mut pubkey_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (key_package, pubkey_package_for_participant) = frost::keys::dkg::part3( - &round2_secret_packages[&participant_identifier], - &received_round1_packages[&participant_identifier], - &received_round2_packages[&participant_identifier], + let round2_secret_package = &round2_secret_packages[&participant_identifier]; + let round1_packages = &received_round1_packages[&participant_identifier]; + let round2_packages = &received_round2_packages[&participant_identifier]; + # // ANCHOR: dkg_part3 + let (key_package, pubkey_package) = frost::keys::dkg::part3( + round2_secret_package, + round1_packages, + round2_packages, )?; + # // ANCHOR_END: dkg_part3 key_packages.insert(participant_identifier, key_package); - pubkey_packages.insert(participant_identifier, pubkey_package_for_participant); + pubkey_packages.insert(participant_identifier, pubkey_package); } // With its own key package and the pubkey package, each participant can now proceed diff --git a/frost-secp256k1/README.md b/frost-secp256k1/README.md index c27042a9..ebc79da5 100644 --- a/frost-secp256k1/README.md +++ b/frost-secp256k1/README.md @@ -9,6 +9,7 @@ scenario in a single thread and it abstracts away any communication between peer ```rust +# // ANCHOR: tkg_gen use frost_secp256k1 as frost; use rand::thread_rng; use std::collections::HashMap; @@ -16,20 +17,23 @@ use std::collections::HashMap; let mut rng = thread_rng(); let max_signers = 5; let min_signers = 3; -let (shares, pubkeys) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?; +let (shares, pubkey_package) = frost::keys::generate_with_dealer(max_signers, min_signers, &mut rng)?; +# // ANCHOR_END: tkg_gen // Verifies the secret shares from the dealer and store them in a HashMap. // In practice, the KeyPackages must be sent to its respective participants // through a confidential and authenticated channel. let mut key_packages: HashMap<_, _> = HashMap::new(); -for (k, v) in shares { - let key_package = frost::keys::KeyPackage::try_from(v)?; - key_packages.insert(k, key_package); +for (identifier, secret_share) in shares { + # // ANCHOR: tkg_verify + let key_package = frost::keys::KeyPackage::try_from(secret_share)?; + # // ANCHOR_END: tkg_verify + key_packages.insert(identifier, key_package); } -let mut nonces = HashMap::new(); -let mut commitments = HashMap::new(); +let mut nonces_map = HashMap::new(); +let mut commitments_map = HashMap::new(); //////////////////////////////////////////////////////////////////////////// // Round 1: generating nonces and signing commitments for each participant @@ -38,43 +42,51 @@ let mut commitments = HashMap::new(); // In practice, each iteration of this loop will be executed by its respective participant. for participant_index in 1..(min_signers as u16 + 1) { let participant_identifier = participant_index.try_into().expect("should be nonzero"); + let key_package = &key_packages[&participant_identifier]; // Generate one (1) nonce and one SigningCommitments instance for each // participant, up to _threshold_. - let (nonce, commitment) = frost::round1::commit( + # // ANCHOR: round1_commit + let (nonces, commitments) = frost::round1::commit( participant_identifier, - key_packages[&participant_identifier].secret_share(), + key_package.secret_share(), &mut rng, ); - // In practice, the nonces and commitment must be sent to the coordinator + # // ANCHOR_END: round1_commit + // In practice, the nonces must be kept by the participant to use in the + // next round, while the commitment must be sent to the coordinator // (or to every other participant if there is no coordinator) using // an authenticated channel. - nonces.insert(participant_identifier, nonce); - commitments.insert(participant_identifier, commitment); + nonces_map.insert(participant_identifier, nonces); + commitments_map.insert(participant_identifier, commitments); } // This is what the signature aggregator / coordinator needs to do: // - decide what message to sign // - take one (unused) commitment per signing participant let mut signature_shares = Vec::new(); +let commitments_received = commitments_map.clone().into_values().collect(); +# // ANCHOR: round2_package let message = "message to sign".as_bytes(); -let comms = commitments.clone().into_values().collect(); -// In practice, the SigningPackage must be sent to all participants -// involved in the current signing (at least min_signers participants), -// using an authenticate channel (and confidential if the message is secret). -let signing_package = frost::SigningPackage::new(comms, message.to_vec()); +# // In practice, the SigningPackage must be sent to all participants +# // involved in the current signing (at least min_signers participants), +# // using an authenticate channel (and confidential if the message is secret). +let signing_package = frost::SigningPackage::new(commitments_received, message.to_vec()); +# // ANCHOR_END: round2_package //////////////////////////////////////////////////////////////////////////// // Round 2: each participant generates their signature share //////////////////////////////////////////////////////////////////////////// // In practice, each iteration of this loop will be executed by its respective participant. -for participant_identifier in nonces.keys() { +for participant_identifier in nonces_map.keys() { let key_package = &key_packages[participant_identifier]; - let nonces_to_use = &nonces[participant_identifier]; + let nonces = &nonces_map[participant_identifier]; // Each participant generates their signature share. - let signature_share = frost::round2::sign(&signing_package, nonces_to_use, key_package)?; + # // ANCHOR: round2_sign + let signature_share = frost::round2::sign(&signing_package, nonces, key_package)?; + # // ANCHOR_END: round2_sign // In practice, the signature share must be sent to the Coordinator // using an authenticated channel. @@ -87,14 +99,20 @@ for participant_identifier in nonces.keys() { //////////////////////////////////////////////////////////////////////////// // Aggregate (also verifies the signature shares) -let group_signature = frost::aggregate(&signing_package, &signature_shares[..], &pubkeys)?; +# // ANCHOR: aggregate +let group_signature = frost::aggregate(&signing_package, &signature_shares[..], &pubkey_package)?; +# // ANCHOR_END: aggregate + // Check that the threshold signature can be verified by the group public // key (the verification key). -assert!(pubkeys +# // ANCHOR: verify +let is_signature_valid = pubkey_package .group_public .verify(message, &group_signature) - .is_ok()); + .is_ok(); +# // ANCHOR_END: verify +assert!(is_signature_valid); # Ok::<(), frost::Error>(()) ``` diff --git a/frost-secp256k1/dkg.md b/frost-secp256k1/dkg.md index c9c108e6..8efe0539 100644 --- a/frost-secp256k1/dkg.md +++ b/frost-secp256k1/dkg.md @@ -25,6 +25,7 @@ they can proceed to sign messages with FROST. ## Example ```rust +# // ANCHOR: dkg_import use rand::thread_rng; use std::collections::HashMap; @@ -32,13 +33,14 @@ use frost_secp256k1 as frost; let mut rng = thread_rng(); +let max_signers = 5; +let min_signers = 3; +# // ANCHOR_END: dkg_import + //////////////////////////////////////////////////////////////////////////// // Key generation, Round 1 //////////////////////////////////////////////////////////////////////////// -let max_signers = 5; -let min_signers = 3; - // Keep track of each participant's round 1 secret package. // In practice each participant will keep its copy; no one // will have all the participant's packages. @@ -53,16 +55,18 @@ let mut received_round1_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (secret_package, round1_package) = frost::keys::dkg::part1( + # // ANCHOR: dkg_part1 + let (round1_secret_package, round1_package) = frost::keys::dkg::part1( participant_identifier, max_signers, min_signers, &mut rng, )?; + # // ANCHOR_END: dkg_part1 // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. - round1_secret_packages.insert(participant_identifier, secret_package); + round1_secret_packages.insert(participant_identifier, round1_secret_package); // "Send" the round 1 package to all other participants. In this // test this is simulated using a HashMap; in practice this will be @@ -99,12 +103,14 @@ let mut received_round2_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (round2_secret_package, round2_packages) = frost::keys::dkg::part2( - round1_secret_packages - .remove(&participant_identifier) - .unwrap(), - &received_round1_packages[&participant_identifier], - )?; + let round1_secret_package = round1_secret_packages + .remove(&participant_identifier) + .unwrap(); + let round1_packages = &received_round1_packages[&participant_identifier]; + # // ANCHOR: dkg_part2 + let (round2_secret_package, round2_packages) = + frost::keys::dkg::part2(round1_secret_package, round1_packages)?; + # // ANCHOR_END: dkg_part2 // Store the participant's secret package for later use. // In practice each participant will store it in their own environment. @@ -142,13 +148,18 @@ let mut pubkey_packages = HashMap::new(); // In practice, each participant will perform this on their own environments. for participant_index in 1..=max_signers { let participant_identifier = participant_index.try_into().expect("should be nonzero"); - let (key_package, pubkey_package_for_participant) = frost::keys::dkg::part3( - &round2_secret_packages[&participant_identifier], - &received_round1_packages[&participant_identifier], - &received_round2_packages[&participant_identifier], + let round2_secret_package = &round2_secret_packages[&participant_identifier]; + let round1_packages = &received_round1_packages[&participant_identifier]; + let round2_packages = &received_round2_packages[&participant_identifier]; + # // ANCHOR: dkg_part3 + let (key_package, pubkey_package) = frost::keys::dkg::part3( + round2_secret_package, + round1_packages, + round2_packages, )?; + # // ANCHOR_END: dkg_part3 key_packages.insert(participant_identifier, key_package); - pubkey_packages.insert(participant_identifier, pubkey_package_for_participant); + pubkey_packages.insert(participant_identifier, pubkey_package); } // With its own key package and the pubkey package, each participant can now proceed diff --git a/rfcs/0001-messages.md b/rfcs/0001-messages.md deleted file mode 100644 index d130451b..00000000 --- a/rfcs/0001-messages.md +++ /dev/null @@ -1,431 +0,0 @@ -# FROST messages - -Proposes a message layout to exchange information between participants of a FROST setup using the [jubjub](https://github.com/zkcrypto/jubjub) curve. - -## Motivation - -Currently FROST library is complete for 2 round signatures with a dealer/aggregator setup. -This proposal acknowledges that specific features, additions and upgrades will need to be made when DKG is implemented. - -Assuming all participants have a FROST library available, we need to define message structures in a way that data can be exchanged between participants. The proposal is a collection of data types so each side can do all the actions needed for a real life situation. - -## Definitions - -- `dealer` - Participant who distributes the initial package to all the other participants. -- `aggregator` - Participant in charge of collecting all the signatures from the other participants and generating the final group signature. -- `signer` - Participant that will receive the initial package, sign and send the signature to the aggregator to receive the final group signature. - -Note: In this RFC we consider the above 3 participants to be different. `dealer` and `aggregator` have specific hard coded `ParticipantId`s, so for example a `dealer` can't be a `signer`. This is not a protocol limitation but a specific rule introduced in this document. - -## Guide-level explanation - -We propose a message separated in 2 parts, a header and a payload: - -```rust -/// The data required to serialize a frost message. -struct Message { - header: Header, - payload: Payload, -} -``` - -`Header` will look as follows: - -```rust -/// The data required to serialize the common header fields for every message. -/// -/// Note: the `msg_type` is derived from the `payload` enum variant. -struct Header { - version: MsgVersion, - sender: ParticipantId, - receiver: ParticipantId, -} -``` - -While `Payload` will be defined as: - -```rust -/// The data required to serialize the payload for a message. -enum Payload { - SharePackage(messages::SharePackage), - SigningCommitments(messages::SigningCommitments), - SigningPackage(messages::SigningPackage), - SignatureShare(messages::SignatureShare), - AggregateSignature(messages::AggregateSignature), -} -``` - -All the messages and new types will be defined in a new file `src/frost/messages.rs` - -## Reference-level explanation - -Here we explore in detail the header types and all the message payloads. - -### Header - -Fields of the header define new types. Proposed implementation for them is as follows: - -```rust -/// The numeric values used to identify each `Payload` variant during serialization. -#[repr(u8)] -#[non_exhaustive] -enum MsgType { - SharePackage, - SigningCommitments, - SigningPackage, - SignatureShare, - AggregateSignature, -} - -/// The numeric values used to identify the protocol version during serialization. -struct MsgVersion(u8); - -const BASIC_FROST_SERIALIZATION: MsgVersion = MsgVersion(0); - -/// The numeric values used to identify each participant during serialization. -/// -/// In the `frost` module, participant ID `0` should be invalid. -/// But in serialization, we want participants to be indexed from `0..n`, -/// where `n` is the number of participants. -/// This helps us look up their shares and commitments in serialized arrays. -/// So in serialization, we assign the dealer and aggregator the highest IDs, -/// and mark those IDs as invalid for signers. Then we serialize the -/// participants in numeric order of their FROST IDs. -/// -/// "When performing Shamir secret sharing, a polynomial `f(x)` is used to generate -/// each party’s share of the secret. The actual secret is `f(0)` and the party with -/// ID `i` will be given a share with value `f(i)`. -/// Since a DKG may be implemented in the future, we recommend that the ID `0` be declared invalid." -/// https://raw.githubusercontent.com/ZcashFoundation/redjubjub/main/zcash-frost-audit-report-20210323.pdf#d -enum ParticipantId { - /// A serialized participant ID for a signer. - /// - /// Must be less than or equal to `MAX_SIGNER_PARTICIPANT_ID`. - Signer(u64), - /// The fixed participant ID for the dealer. - Dealer, - /// The fixed participant ID for the aggregator. - Aggregator, -} - -/// The fixed participant ID for the dealer. -const DEALER_PARTICIPANT_ID: u64 = u64::MAX - 1; - -/// The fixed participant ID for the aggregator. -const AGGREGATOR_PARTICIPANT_ID: u64 = u64::MAX; - -/// The maximum `ParticipantId::Signer` in this serialization format. -/// -/// We reserve two participant IDs for the dealer and aggregator. -const MAX_SIGNER_PARTICIPANT_ID: u64 = u64::MAX - 2; -``` - -### Payloads - -Each payload defines a new message: - -```rust -/// The data required to serialize `frost::SharePackage`. -/// -/// The dealer sends this message to each signer for this round. -/// With this, the signer should be able to build a `SharePackage` and use -/// the `sign()` function. -/// -/// Note: `frost::SharePackage.public` can be calculated from `secret_share`. -struct messages::SharePackage { - /// The public signing key that represents the entire group: - /// `frost::SharePackage.group_public`. - group_public: VerificationKey, - /// This participant's secret key share: `frost::SharePackage.share.value`. - secret_share: frost::Secret, - /// The commitments to the coefficients for our secret polynomial _f_, - /// used to generate participants' key shares. Participants use these to perform - /// verifiable secret sharing. - /// Share packages that contain duplicate or missing `ParticipantId`s are invalid. - /// `ParticipantId`s must be serialized in ascending numeric order. - share_commitment: BTreeMap, -} - -/// The data required to serialize `frost::SigningCommitments`. -/// -/// Each signer must send this message to the aggregator. -/// A signing commitment from the first round of the signing protocol. -struct messages::SigningCommitments { - /// The hiding point: `frost::SigningCommitments.hiding` - hiding: frost::Commitment, - /// The binding point: `frost::SigningCommitments.binding` - binding: frost::Commitment, -} - -/// The data required to serialize `frost::SigningPackage`. -/// -/// The aggregator decides what message is going to be signed and -/// sends it to each signer with all the commitments collected. -struct messages::SigningPackage { - /// The collected commitments for each signer as an ordered map of - /// unique participant identifiers: `frost::SigningPackage.signing_commitments` - /// - /// Signing packages that contain duplicate or missing `ParticipantId`s are invalid. - /// `ParticipantId`s must be serialized in ascending numeric order. - signing_commitments: BTreeMap, - /// The message to be signed: `frost::SigningPackage.message`. - /// - /// Each signer should perform protocol-specific verification on the message. - message: Vec, -} - -/// The data required to serialize `frost::SignatureShare`. -/// -/// Each signer sends their signatures to the aggregator who is going to collect them -/// and generate a final spend signature. -struct messages::SignatureShare { - /// This participant's signature over the message: `frost::SignatureShare.signature` - signature: frost::SignatureResponse, -} - -/// The data required to serialize a successful output from `frost::aggregate()`. -/// -/// The final signature is broadcasted by the aggregator to all signers. -struct messages::AggregateSignature { - /// The aggregated group commitment: `Signature.r_bytes` returned by `frost::aggregate` - group_commitment: frost::GroupCommitment, - /// A plain Schnorr signature created by summing all the signature shares: - /// `Signature.s_bytes` returned by `frost::aggregate` - schnorr_signature: frost::SignatureResponse, -} -``` - -## Validation - -Validation is implemented to each new data type as needed. This will ensure the creation of valid messages before they are send and right after they are received. We create a trait for this as follows: - -```rust -pub trait Validate { - fn validate(&self) -> Result<&Self, MsgErr>; -} -``` - -And we implement where needed. For example, in the header, sender and receiver can't be the same: - -```rust -impl Validate for Header { - fn validate(&self) -> Result<&Self, MsgErr> { - if self.sender.0 == self.receiver.0 { - return Err(MsgErr::SameSenderAndReceiver); - } - Ok(self) - } -} -``` - -This will require to have validation error messages as: - -```rust -use thiserror::Error; - -#[derive(Clone, Error, Debug)] -pub enum MsgErr { - #[error("sender and receiver are the same")] - SameSenderAndReceiver, -} -``` - -Then to create a valid `Header` in the sender side we call: - -```rust -let header = Validate::validate(&Header { - .. -}).expect("a valid header"); -``` - -The receiver side will validate the header using the same method. Instead of panicking the error can be ignored to don't crash and keep waiting for other (potentially valid) messages. - -```rust -if let Ok(header) = msg.header.validate() { - .. -} -``` - -### Rules - -The following rules must be implemented: - -#### Header - -- `version` must be a supported version. -- `sender` and `receiver` can't be the same. -- The `ParticipantId` variants of `sender` and `receiver` must match the message type. - -#### Payloads - -- Each jubjub type must be validated during deserialization. -- `share_commitments`: - - Length must be less than or equal to `MAX_SIGNER_PARTICIPANT_ID`. - - Length must be at least `MIN_SIGNERS` (`2` signers). - - Duplicate `ParticipantId`s are invalid. This is implicit in the use of `BTreeMap` during serialization, but must be checked during deserialization. - - Commitments must be serialized in ascending numeric `ParticipantId` order. This is the order of `BTreeMap.iter` during serialization, but must be checked during deserialization. -- `signing_commitments`: - - Length must be less than or equal to `MAX_SIGNER_PARTICIPANT_ID`. - - Length must be at least `MIN_THRESHOLD` (`2` required signers). - - Signing packages that contain duplicate `ParticipantId`s are invalid. This is implicit in the use of `BTreeMap` during serialization, but must be checked during deserialization. - - Signing packages must serialize in ascending numeric `ParticipantId` order. This is the order of `BTreeMap.iter` during serialization, but must be checked during deserialization.. -- `message`: signed messages have a protocol-specific length limit. For Zcash, that limit is the maximum network protocol message length: `2^21` bytes (2 MB). - -## Serialization/Deserialization - -Each message struct needs to serialize to bytes representation before it is sent through the wire and must deserialize to the same struct (round trip) on the receiver side. We use `serde` and macro derivations (`Serialize` and `Deserialize`) to automatically implement where possible. - -This will require deriving serde in several types defined in `frost.rs`. -Manual implementation of serialization/deserialization will be located at a new mod `src/frost/serialize.rs`. - -### Byte order - -Each byte chunk specified below is in little-endian order unless is specified otherwise. - -Multi-byte integers **must not** be used for serialization, because they have different byte orders on different platforms. - -### Header - -The `Header` part of the message is 18 bytes total: - -Bytes | Field name | Data type -------|------------|----------- -1 | version | u8 -1 | msg_type | u8 -8 | sender | u64 -8 | receiver | u64 - -### Frost types - -The FROST types we will be using in the messages can be represented always as a primitive type. For serialization/deserialization purposes: - -- `Commitment` = `AffinePoint` -- `Secret` = `Scalar` -- `GroupCommitment` = `AffinePoint` -- `SignatureResponse` = `Scalar` - -### Primitive types - -`Payload`s use data types that we need to specify first. We have 3 primitive types inside the payload messages: - -#### `Scalar` - -`jubjub::Scalar` is a an alias for `jubjub::Fr`. We use `Scalar::to_bytes` and `Scalar::from_bytes` to get a 32-byte little-endian canonical representation. See https://github.com/zkcrypto/bls12_381/blob/main/src/scalar.rs#L260 and https://github.com/zkcrypto/bls12_381/blob/main/src/scalar.rs#L232 - -#### `AffinePoint` - -Much of the math in FROST is done using `jubjub::ExtendedPoint`. But for message exchange `jubjub::AffinePoint`s are a better choice, as their byte representation is smaller. - -Conversion from one type to the other is trivial: - -https://docs.rs/jubjub/0.6.0/jubjub/struct.AffinePoint.html#impl-From%3CExtendedPoint%3E -https://docs.rs/jubjub/0.6.0/jubjub/struct.ExtendedPoint.html#impl-From%3CAffinePoint%3E - -We use `AffinePoint::to_bytes` and `AffinePoint::from_bytes` to get a 32-byte little-endian canonical representation. See https://github.com/zkcrypto/jubjub/blob/main/src/lib.rs#L443 - -#### VerificationKey - -`redjubjub::VerificationKey`s can be serialized and deserialized using `<[u8; 32]>::from` and `VerificationKey::from`. See https://github.com/ZcashFoundation/redjubjub/blob/main/src/verification_key.rs#L80-L90 and https://github.com/ZcashFoundation/redjubjub/blob/main/src/verification_key.rs#L114-L121. - -### Payload - -Payload part of the message is variable in size and depends on message type. - -#### `SharePackage` - -Bytes | Field name | Data type -----------------|------------------|----------- -32 | group_public | VerificationKey -32 | secret_share | Share -1 | participants | u8 -(8+32)*participants | share_commitment | BTreeMap - -#### `SigningCommitments` - -Bytes | Field name | Data type ---------|---------------------|----------- -32 | hiding | Commitment -32 | binding | Commitment - -#### `SigningPackage` - -Bytes | Field name | Data type ------------------------|--------------------|----------- -1 | participants | u8 -(8+32+32)*participants | signing_commitments| BTreeMap -8 | message_length | u64 -message_length | message | Vec\ - - -#### `SignatureShare` - -Bytes | Field name | Data type -------|------------|----------- -32 | signature | SignatureResponse - -#### `AggregateSignature` - -Bytes | Field name | Data type -------|------------------|----------- -32 | group_commitment | GroupCommitment -32 | schnorr_signature| SignatureResponse - -## Not included - -The following are a few things this RFC is not considering: - -- The RFC does not describe implementation-specific issues - it is focused on message structure and serialization. -- Implementations using this serialization should handle missing messages using timeouts or similar protocol-specific mechanisms. - - This is particularly important for `SigningPackage`s, which only need a threshold of participants to continue. -- Messages larger than 4 GB are not supported on 32-bit platforms. -- Implementations should validate that message lengths are lower than a protocol-specific maximum length, then allocate message memory. -- Implementations should distinguish between FROST messages from different signature schemes using implementation-specific mechanisms. - -### State-Based Validation - -The following validation rules should be checked by the implementation: - -- `share_commitments`: The number of participants in each round is set by the length of `share_commitments`. - - If `sender` and `receiver` are a `ParticipantId::Signer`, they must be less than the number of participants in this round. - - The length of `signing_commitments` must be less than or equal to the number of participants in this round. -- `signing_commitments`: Signing packages that contain missing `ParticipantId`s are invalid - - Note: missing participants are supported by this serialization format. - But implementations can require all participants to fully participate in each round. - -If the implementation knows the number of key shares, it should re-check all the validation rules involving `MAX_SIGNER_PARTICIPANT_ID` using that lower limit. - -## Testing plan - -### Test Vectors - -#### Conversion on Test Vectors - -- Test conversion from `frost` to `message` on a test vector - 1. Implement the Rust `message` struct - 2. Implement conversion from and to the `frost` type - 3. Do a round-trip test from `frost` to `message` on a test vector -- Test conversion from `message` to bytes on a test vector - 1. Implement conversion from and to the `message` type - 2. Do a round-trip test from `message` to bytes on a test vector - -#### Signing Rounds on Test Vectors - -- Test signing using `frost` types on a test vector - 1. Implement a single round of `frost` signing using a test vector -- Test signing using `message` types on a test vector -- Test signing using byte vectors on a test vector - -### Property Tests - -#### Conversion Property Tests - -- Create property tests for each message - - Test round-trip conversion from `frost` to `message` types - - Test round-trip serialization and deserialization for each `message` type - -#### Signing Round Property Tests - -- Create property tests for signing rounds - - Test a signing round with `frost` types - - Test a signing round with `message` types - - Test a signing round with byte vectors