improve book per audit report (#491)
* improve book per audit report * remove stale sentence * fix a typo * Update book/src/tutorial/signing.md Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> * Update book/src/tutorial/signing.md --------- Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
This commit is contained in:
parent
386de4de6f
commit
d439fdc93d
|
@ -3,6 +3,9 @@
|
|||
[ZF FROST](index.md)
|
||||
- [Understanding FROST](frost.md)
|
||||
- [Tutorial](tutorial.md)
|
||||
- [Importing and General Information](tutorial/importing.md)
|
||||
- [Trusted Dealer Key Generation](tutorial/trusted-dealer.md)
|
||||
- [Signing](tutorial/signing.md)
|
||||
- [Distributed Key Generation](tutorial/dkg.md)
|
||||
- [User Documentation](user.md)
|
||||
- [Terminology](terminology.md)
|
||||
|
|
|
@ -15,228 +15,3 @@ If you need to support multiple ciphersuites then feel free to use
|
|||
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.)
|
||||
|
|
|
@ -20,11 +20,19 @@ 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
|
||||
// Ask the user which identifier they would like to use. You can create
|
||||
// an identifier from a non-zero u16 or derive from an arbitrary string.
|
||||
// Some fixed examples follow (each participant must choose a different identifier)
|
||||
{{#include ../../../frost-ristretto255/tests/integration_tests.rs:dkg_identifier}}
|
||||
|
||||
{{#include ../../../frost-ristretto255/dkg.md:dkg_part1}}
|
||||
```
|
||||
|
||||
```admonish info
|
||||
Check the crate documentation for a [full working example](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/keys/dkg/index.html#example); keep in mind it's an artificial
|
||||
one since everything runs in the same program.
|
||||
```
|
||||
|
||||
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
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# Importing and General Information
|
||||
|
||||
## Including `frost-ristretto255`
|
||||
|
||||
Add to your `Cargo.toml` file:
|
||||
|
||||
```
|
||||
[dependencies]
|
||||
frost-ristretto255 = "0.6.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. While the ZF FROST library does not handle communication, it can
|
||||
help with serialization by activating the `serde` feature. When it is enabled,
|
||||
you can use [serde](https://serde.rs/) to serialize any structure that needs
|
||||
to be transmitted. Import example:
|
||||
|
||||
```
|
||||
[dependencies]
|
||||
frost-ristretto255 = { version = "0.6.0", features = ["serde"] }
|
||||
```
|
||||
|
||||
Note that serde usage is optional. Applications can use different encodings, and
|
||||
to support that, all structures that need to be transmitted have public getters
|
||||
and `new()` methods allowing the application to encode and decode them as it
|
||||
wishes. (Note that fields like `Scalar` and `Element` do have standard byte
|
||||
string encodings; the application can encode those byte strings as it wishes,
|
||||
as well the structure themselves and things like maps and lists.)
|
|
@ -0,0 +1,114 @@
|
|||
# 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](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#peer-to-peer-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
|
||||
in the `SigningPackage` 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.)
|
|
@ -0,0 +1,81 @@
|
|||
# Trusted Dealer Key Generation
|
||||
|
||||
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](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
|
||||
Check the crate documentation for a [full working example](https://docs.rs/frost-ristretto255/latest/frost_ristretto255/index.html#example-key-generation-with-trusted-dealer-and-frost-signing); keep in mind it's an artificial
|
||||
one since everything runs in the same program.
|
||||
```
|
||||
|
||||
```admonish info
|
||||
You can specify which identifiers to use by using [`IdentifierList::Custom`](https://docs.rs/frost-core/latest/frost_core/frost/keys/enum.IdentifierList.html#variant.Custom). Refer to the [DKG](dkg.md#part-1) section for an example on how to create identifiers.
|
||||
```
|
||||
|
||||
```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.
|
||||
```
|
|
@ -194,6 +194,17 @@ fn check_identifier_derivation() {
|
|||
frost_core::tests::ciphersuite_generic::check_identifier_derivation::<Ed25519Sha512>();
|
||||
}
|
||||
|
||||
// Explicit test which is used in a documentation snippet
|
||||
#[test]
|
||||
#[allow(unused_variables)]
|
||||
fn check_identifier_generation() -> Result<(), Error> {
|
||||
// ANCHOR: dkg_identifier
|
||||
let participant_identifier = Identifier::try_from(7u16)?;
|
||||
let participant_identifier = Identifier::derive("alice@example.com".as_bytes())?;
|
||||
// ANCHOR_END: dkg_identifier
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_sign_with_dealer_and_identifiers() {
|
||||
let rng = thread_rng();
|
||||
|
|
|
@ -194,6 +194,17 @@ fn check_identifier_derivation() {
|
|||
frost_core::tests::ciphersuite_generic::check_identifier_derivation::<Ed448Shake256>();
|
||||
}
|
||||
|
||||
// Explicit test which is used in a documentation snippet
|
||||
#[test]
|
||||
#[allow(unused_variables)]
|
||||
fn check_identifier_generation() -> Result<(), Error> {
|
||||
// ANCHOR: dkg_identifier
|
||||
let participant_identifier = Identifier::try_from(7u16)?;
|
||||
let participant_identifier = Identifier::derive("alice@example.com".as_bytes())?;
|
||||
// ANCHOR_END: dkg_identifier
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_sign_with_dealer_and_identifiers() {
|
||||
let rng = thread_rng();
|
||||
|
|
|
@ -192,6 +192,17 @@ fn check_identifier_derivation() {
|
|||
frost_core::tests::ciphersuite_generic::check_identifier_derivation::<P256Sha256>();
|
||||
}
|
||||
|
||||
// Explicit test which is used in a documentation snippet
|
||||
#[test]
|
||||
#[allow(unused_variables)]
|
||||
fn check_identifier_generation() -> Result<(), Error> {
|
||||
// ANCHOR: dkg_identifier
|
||||
let participant_identifier = Identifier::try_from(7u16)?;
|
||||
let participant_identifier = Identifier::derive("alice@example.com".as_bytes())?;
|
||||
// ANCHOR_END: dkg_identifier
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_sign_with_dealer_and_identifiers() {
|
||||
let rng = thread_rng();
|
||||
|
|
|
@ -194,6 +194,17 @@ fn check_identifier_derivation() {
|
|||
frost_core::tests::ciphersuite_generic::check_identifier_derivation::<Ristretto255Sha512>();
|
||||
}
|
||||
|
||||
// Explicit test which is used in a documentation snippet
|
||||
#[test]
|
||||
#[allow(unused_variables)]
|
||||
fn check_identifier_generation() -> Result<(), Error> {
|
||||
// ANCHOR: dkg_identifier
|
||||
let participant_identifier = Identifier::try_from(7u16)?;
|
||||
let participant_identifier = Identifier::derive("alice@example.com".as_bytes())?;
|
||||
// ANCHOR_END: dkg_identifier
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_sign_with_dealer_and_identifiers() {
|
||||
let rng = thread_rng();
|
||||
|
|
|
@ -194,6 +194,17 @@ fn check_identifier_derivation() {
|
|||
frost_core::tests::ciphersuite_generic::check_identifier_derivation::<Secp256K1Sha256>();
|
||||
}
|
||||
|
||||
// Explicit test which is used in a documentation snippet
|
||||
#[test]
|
||||
#[allow(unused_variables)]
|
||||
fn check_identifier_generation() -> Result<(), Error> {
|
||||
// ANCHOR: dkg_identifier
|
||||
let participant_identifier = Identifier::try_from(7u16)?;
|
||||
let participant_identifier = Identifier::derive("alice@example.com".as_bytes())?;
|
||||
// ANCHOR_END: dkg_identifier
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_sign_with_dealer_and_identifiers() {
|
||||
let rng = thread_rng();
|
||||
|
|
Loading…
Reference in New Issue