Reserve specific participant IDs for the dealer and aggregator

Also explicitly identify the sender and receiver for each message.
This commit is contained in:
teor 2021-05-13 18:34:36 +10:00 committed by Deirdre Connolly
parent 4f2b53d838
commit df0ec420d4
1 changed files with 29 additions and 8 deletions

View File

@ -81,7 +81,25 @@ struct MsgVersion(u8);
const BASIC_FROST_SERIALIZATION: MsgVersion = MsgVersion(0); const BASIC_FROST_SERIALIZATION: MsgVersion = MsgVersion(0);
/// The numeric values used to identify each participant during serialization. /// The numeric values used to identify each participant during serialization.
struct ParticipantId(u8); ///
/// 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 to IDs `254` and `255`.
///
/// "When performing Shamir secret sharing, a polynomial `f(x)` is used to generate each partys 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 {
Signer(u8),
Dealer,
Aggregator,
}
/// The maximum `ParticipantId::Signer` in this serialization format.
///
/// We reserve two participant IDs for the dealer and aggregator.
const MAX_SIGNER_PARTICIPANT_ID: u8 = u8::MAX - 2;
``` ```
### Payloads ### Payloads
@ -91,8 +109,8 @@ Each payload defines a new message:
```rust ```rust
/// The data required to serialize `frost::SharePackage`. /// The data required to serialize `frost::SharePackage`.
/// ///
/// Dealer must send this message with initial data to each participant involved. /// The dealer sends this message to each signer for this round.
/// With this, the participant should be able to build a `SharePackage` and use /// With this, the signer should be able to build a `SharePackage` and use
/// the `sign()` function. /// the `sign()` function.
/// ///
/// Note: `frost::SharePackage.public` can be calculated from `secret_share`. /// Note: `frost::SharePackage.public` can be calculated from `secret_share`.
@ -110,6 +128,7 @@ struct messages::SharePackage {
/// The data required to serialize `frost::SigningCommitments`. /// 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. /// A signing commitment from the first round of the signing protocol.
struct messages::SigningCommitments { struct messages::SigningCommitments {
/// The hiding point: `frost::SigningCommitments.hiding` /// The hiding point: `frost::SigningCommitments.hiding`
@ -121,7 +140,7 @@ struct messages::SigningCommitments {
/// The data required to serialize `frost::SigningPackage`. /// The data required to serialize `frost::SigningPackage`.
/// ///
/// The aggregator decides what message is going to be signed and /// The aggregator decides what message is going to be signed and
/// sends it to each participant with all the commitments collected. /// sends it to each signer with all the commitments collected.
struct messages::SigningPackage { struct messages::SigningPackage {
/// The message to be signed: `frost::SigningPackage.message` /// The message to be signed: `frost::SigningPackage.message`
message: Vec<u8>, message: Vec<u8>,
@ -144,7 +163,7 @@ struct messages::SignatureShare {
/// The data required to serialize a successful output from `frost::aggregate()`. /// The data required to serialize a successful output from `frost::aggregate()`.
/// ///
/// The final signature is broadcasted by the aggregator to any participant. /// The final signature is broadcasted by the aggregator to all signers.
struct messages::AggregateSignature { struct messages::AggregateSignature {
/// The aggregated group commitment: `Signature<SpendAuth>.r_bytes` returned by `frost::aggregate` /// The aggregated group commitment: `Signature<SpendAuth>.r_bytes` returned by `frost::aggregate`
group_commitment: jubjub::AffinePoint, group_commitment: jubjub::AffinePoint,
@ -214,17 +233,19 @@ The following rules must be implemented:
- `msg_type` must be a known `MsgType` value. - `msg_type` must be a known `MsgType` value.
- `version` must be a supported version. - `version` must be a supported version.
- `sender` and `receiver` can't be the same. - `sender` and `receiver` can't be the same.
- `sender` and `receiver` must be less than the maximum number of participants. - If `sender` and `receiver` are a `ParticipantId::Signer`, they must be less than the number of participants in this round.
- The `ParticipantId` variants of `sender` and `receiver` must match the message type.
#### Payloads #### Payloads
- Each jubjub type must be validated during deserialization. - Each jubjub type must be validated during deserialization.
- `share_commitments`: For each round, the maximum number of participants is set by the length of `share_commitments`. - `share_commitments`: The number of participants in each round is set by the length of `share_commitments`.
- The number of participants in each round must be less than or equal to `MAX_SIGNER_PARTICIPANT_ID`.
- `signing_commitments`: - `signing_commitments`:
- Signing packages that contain duplicate `ParticipantID`s are invalid - Signing packages that contain duplicate `ParticipantID`s are invalid
- Signing packages that contain missing `ParticipantID`s are invalid - Signing packages that contain missing `ParticipantID`s are invalid
- TODO: check if missing participants are allowed - TODO: check if missing participants are allowed
- The length of `signing_commitments` must be less than or equal to the length of the `share_commitments` for this round. - The length of `signing_commitments` must be less than or equal to the number of participants in this round.
- `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). - `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 ## Serialization/Deserialization