implement common traits for public types (#422)

This commit is contained in:
Conrado Gouvea 2023-06-30 16:15:56 -03:00 committed by GitHub
parent 4e134f50d6
commit 8531855bd7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 430 additions and 18 deletions

View File

@ -184,7 +184,7 @@ fn derive_interpolating_value<C: Ciphersuite>(
/// Generated by the coordinator of the signing operation and distributed to
/// each signing party
#[derive(Clone, PartialEq, Eq, Getters)]
#[derive(Clone, Debug, PartialEq, Eq, Getters)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
pub struct SigningPackage<C: Ciphersuite> {

View File

@ -74,9 +74,7 @@ where
C: Ciphersuite,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("SigningShare")
.field(&hex::encode(self.to_bytes()))
.finish()
f.debug_tuple("SigningShare").field(&"<redacted>").finish()
}
}
@ -230,6 +228,17 @@ where
}
}
impl<C> Debug for CoefficientCommitment<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("CoefficientCommitment")
.field(&hex::encode(self.serialize()))
.finish()
}
}
#[cfg(feature = "serde")]
impl<C> TryFrom<ElementSerialization<C>> for CoefficientCommitment<C>
where
@ -264,7 +273,7 @@ where
/// [`VerifiableSecretSharingCommitment`], either by performing pairwise comparison, or by using
/// some agreed-upon public location for publication, where each participant can
/// ensure that they received the correct (and same) value.
#[derive(Clone, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct VerifiableSecretSharingCommitment<C: Ciphersuite>(
pub(crate) Vec<CoefficientCommitment<C>>,
@ -306,7 +315,7 @@ where
///
/// To derive a FROST keypair, the receiver of the [`SecretShare`] *must* call
/// .into(), which under the hood also performs validation.
#[derive(Clone, Zeroize, PartialEq, Eq, Getters)]
#[derive(Clone, Debug, Zeroize, PartialEq, Eq, Getters)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
pub struct SecretShare<C: Ciphersuite> {
@ -509,7 +518,7 @@ fn evaluate_vss<C: Ciphersuite>(
/// When using a central dealer, [`SecretShare`]s are distributed to
/// participants, who then perform verification, before deriving
/// [`KeyPackage`]s, which they store to later use during signing.
#[derive(Clone, PartialEq, Eq, Getters)]
#[derive(Clone, Debug, PartialEq, Eq, Getters)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
pub struct KeyPackage<C: Ciphersuite> {
@ -586,7 +595,7 @@ where
/// group public key.
///
/// Used for verification purposes before publishing a signature.
#[derive(Clone, PartialEq, Eq, Getters)]
#[derive(Clone, Debug, PartialEq, Eq, Getters)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
pub struct PublicKeyPackage<C: Ciphersuite> {

View File

@ -53,7 +53,7 @@ pub mod round1 {
/// The package that must be broadcast by each participant to all other participants
/// between the first and second parts of the DKG protocol (round 1).
#[derive(Clone, PartialEq, Eq, Getters)]
#[derive(Clone, Debug, PartialEq, Eq, Getters)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
pub struct Package<C: Ciphersuite> {
@ -101,7 +101,7 @@ pub mod round1 {
/// # Security
///
/// This package MUST NOT be sent to other participants!
#[derive(Clone)]
#[derive(Clone, PartialEq, Eq)]
pub struct SecretPackage<C: Ciphersuite> {
/// The identifier of the participant holding the secret.
pub(crate) identifier: Identifier<C>,
@ -113,6 +113,20 @@ pub mod round1 {
/// The total number of signers.
pub(crate) max_signers: u16,
}
impl<C> std::fmt::Debug for SecretPackage<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SecretPackage")
.field("identifier", &self.identifier)
.field("coefficients", &"<redacted>")
.field("commitment", &self.commitment)
.field("max_signers", &self.max_signers)
.finish()
}
}
}
/// DKG Round 2 structures.
@ -128,7 +142,7 @@ pub mod round2 {
/// # Security
///
/// The package must be sent on an *confidential* and *authenticated* channel.
#[derive(Clone, PartialEq, Eq, Getters)]
#[derive(Clone, Debug, PartialEq, Eq, Getters)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
pub struct Package<C: Ciphersuite> {
@ -176,6 +190,7 @@ pub mod round2 {
/// # Security
///
/// This package MUST NOT be sent to other participants!
#[derive(Clone, PartialEq, Eq)]
pub struct SecretPackage<C: Ciphersuite> {
/// The identifier of the participant holding the secret.
pub(crate) identifier: Identifier<C>,
@ -186,6 +201,20 @@ pub mod round2 {
/// The total number of signers.
pub(crate) max_signers: u16,
}
impl<C> std::fmt::Debug for SecretPackage<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SecretPackage")
.field("identifier", &self.identifier)
.field("commitment", &self.commitment)
.field("secret_share", &"<redacted>")
.field("max_signers", &self.max_signers)
.finish()
}
}
}
/// Performs the first part of the distributed key generation protocol

View File

@ -251,7 +251,7 @@ where
///
/// This step can be batched if desired by the implementation. Each
/// SigningCommitment can be used for exactly *one* signature.
#[derive(Copy, Clone, Eq, PartialEq, Getters)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Getters)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(deny_unknown_fields))]
pub struct SigningCommitments<C: Ciphersuite> {

View File

@ -5,7 +5,7 @@ use rand_core::{CryptoRng, RngCore};
use crate::{random_nonzero, Ciphersuite, Error, Field, Group, Scalar, Signature, VerifyingKey};
/// A signing key for a Schnorr signature on a FROST [`Ciphersuite::Group`].
#[derive(Copy, Clone)]
#[derive(Copy, Clone, PartialEq, Eq)]
pub struct SigningKey<C>
where
C: Ciphersuite,
@ -53,6 +53,15 @@ where
}
}
impl<C> std::fmt::Debug for SigningKey<C>
where
C: Ciphersuite,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("SigningKey").field(&"<redacted>").finish()
}
}
impl<C> From<&SigningKey<C>> for VerifyingKey<C>
where
C: Ciphersuite,

View File

@ -5,7 +5,6 @@ use crate::{
frost::{self, Identifier},
Error, Field, Group, Signature, VerifyingKey,
};
use debugless_unwrap::DebuglessUnwrapErr;
use rand_core::{CryptoRng, RngCore};
use crate::Ciphersuite;
@ -44,7 +43,7 @@ pub fn check_share_generation<C: Ciphersuite, R: RngCore + CryptoRng>(mut rng: R
// Test error cases
assert_eq!(
frost::keys::reconstruct::<C>(&[]).debugless_unwrap_err(),
frost::keys::reconstruct::<C>(&[]).unwrap_err(),
Error::IncorrectNumberOfShares
);
@ -52,7 +51,7 @@ pub fn check_share_generation<C: Ciphersuite, R: RngCore + CryptoRng>(mut rng: R
secret_shares[0] = secret_shares[1].clone();
assert_eq!(
frost::keys::reconstruct::<C>(&secret_shares).debugless_unwrap_err(),
frost::keys::reconstruct::<C>(&secret_shares).unwrap_err(),
Error::DuplicatedShares
);
}
@ -375,7 +374,7 @@ pub fn check_sign_with_dealer_and_identifiers<C: Ciphersuite, R: RngCore + Crypt
frost::keys::IdentifierList::Custom(&identifiers),
&mut rng,
)
.debugless_unwrap_err();
.unwrap_err();
assert_eq!(err, Error::DuplicatedIdentifier);
// Check correct case
@ -418,7 +417,7 @@ fn check_part2_error<C: Ciphersuite>(
let one = <<C as Ciphersuite>::Group as Group>::Field::one();
// Corrupt a PoK
round1_packages[0].proof_of_knowledge.z = round1_packages[0].proof_of_knowledge.z + one;
let e = frost::keys::dkg::part2(round1_secret_package, &round1_packages).debugless_unwrap_err();
let e = frost::keys::dkg::part2(round1_secret_package, &round1_packages).unwrap_err();
assert_eq!(e.culprit(), Some(*round1_packages[0].sender_identifier()));
assert_eq!(
e,

View File

@ -0,0 +1,73 @@
#![cfg(feature = "serde")]
mod helpers;
use frost_ed25519::SigningKey;
use helpers::samples;
use rand::thread_rng;
fn check_common_traits_for_type<T: Clone + Eq + PartialEq + std::fmt::Debug>(v: T) {
// Make sure can be debug-printed. This also catches if the Debug does not
// have an endless recursion (a popular mistake).
println!("{:?}", v);
// Test Clone and Eq
assert_eq!(v, v.clone());
// Make sure it can be unwrapped in a Result (which requires Debug).
let e: Result<T, ()> = Ok(v.clone());
assert_eq!(v, e.unwrap());
}
#[test]
fn check_signing_key_common_traits() {
let mut rng = thread_rng();
let signing_key = SigningKey::new(&mut rng);
check_common_traits_for_type(signing_key);
}
#[test]
fn check_signing_commitments_common_traits() {
let commitments = samples::signing_commitments();
check_common_traits_for_type(commitments);
}
#[test]
fn check_signing_package_common_traits() {
let signing_package = samples::signing_package();
check_common_traits_for_type(signing_package);
}
#[test]
fn check_signature_share_common_traits() {
let signature_share = samples::signature_share();
check_common_traits_for_type(signature_share);
}
#[test]
fn check_secret_share_common_traits() {
let secret_share = samples::secret_share();
check_common_traits_for_type(secret_share);
}
#[test]
fn check_key_package_common_traits() {
let key_package = samples::key_package();
check_common_traits_for_type(key_package);
}
#[test]
fn check_public_key_package_common_traits() {
let public_key_package = samples::public_key_package();
check_common_traits_for_type(public_key_package);
}
#[test]
fn check_round1_package_common_traits() {
let round1_package = samples::round1_package();
check_common_traits_for_type(round1_package);
}
#[test]
fn check_round2_package_common_traits() {
let round2_package = samples::round2_package();
check_common_traits_for_type(round2_package);
}

View File

@ -0,0 +1,73 @@
#![cfg(feature = "serde")]
mod helpers;
use frost_ed448::SigningKey;
use helpers::samples;
use rand::thread_rng;
fn check_common_traits_for_type<T: Clone + Eq + PartialEq + std::fmt::Debug>(v: T) {
// Make sure can be debug-printed. This also catches if the Debug does not
// have an endless recursion (a popular mistake).
println!("{:?}", v);
// Test Clone and Eq
assert_eq!(v, v.clone());
// Make sure it can be unwrapped in a Result (which requires Debug).
let e: Result<T, ()> = Ok(v.clone());
assert_eq!(v, e.unwrap());
}
#[test]
fn check_signing_key_common_traits() {
let mut rng = thread_rng();
let signing_key = SigningKey::new(&mut rng);
check_common_traits_for_type(signing_key);
}
#[test]
fn check_signing_commitments_common_traits() {
let commitments = samples::signing_commitments();
check_common_traits_for_type(commitments);
}
#[test]
fn check_signing_package_common_traits() {
let signing_package = samples::signing_package();
check_common_traits_for_type(signing_package);
}
#[test]
fn check_signature_share_common_traits() {
let signature_share = samples::signature_share();
check_common_traits_for_type(signature_share);
}
#[test]
fn check_secret_share_common_traits() {
let secret_share = samples::secret_share();
check_common_traits_for_type(secret_share);
}
#[test]
fn check_key_package_common_traits() {
let key_package = samples::key_package();
check_common_traits_for_type(key_package);
}
#[test]
fn check_public_key_package_common_traits() {
let public_key_package = samples::public_key_package();
check_common_traits_for_type(public_key_package);
}
#[test]
fn check_round1_package_common_traits() {
let round1_package = samples::round1_package();
check_common_traits_for_type(round1_package);
}
#[test]
fn check_round2_package_common_traits() {
let round2_package = samples::round2_package();
check_common_traits_for_type(round2_package);
}

View File

@ -0,0 +1,73 @@
#![cfg(feature = "serde")]
mod helpers;
use frost_p256::SigningKey;
use helpers::samples;
use rand::thread_rng;
fn check_common_traits_for_type<T: Clone + Eq + PartialEq + std::fmt::Debug>(v: T) {
// Make sure can be debug-printed. This also catches if the Debug does not
// have an endless recursion (a popular mistake).
println!("{:?}", v);
// Test Clone and Eq
assert_eq!(v, v.clone());
// Make sure it can be unwrapped in a Result (which requires Debug).
let e: Result<T, ()> = Ok(v.clone());
assert_eq!(v, e.unwrap());
}
#[test]
fn check_signing_key_common_traits() {
let mut rng = thread_rng();
let signing_key = SigningKey::new(&mut rng);
check_common_traits_for_type(signing_key);
}
#[test]
fn check_signing_commitments_common_traits() {
let commitments = samples::signing_commitments();
check_common_traits_for_type(commitments);
}
#[test]
fn check_signing_package_common_traits() {
let signing_package = samples::signing_package();
check_common_traits_for_type(signing_package);
}
#[test]
fn check_signature_share_common_traits() {
let signature_share = samples::signature_share();
check_common_traits_for_type(signature_share);
}
#[test]
fn check_secret_share_common_traits() {
let secret_share = samples::secret_share();
check_common_traits_for_type(secret_share);
}
#[test]
fn check_key_package_common_traits() {
let key_package = samples::key_package();
check_common_traits_for_type(key_package);
}
#[test]
fn check_public_key_package_common_traits() {
let public_key_package = samples::public_key_package();
check_common_traits_for_type(public_key_package);
}
#[test]
fn check_round1_package_common_traits() {
let round1_package = samples::round1_package();
check_common_traits_for_type(round1_package);
}
#[test]
fn check_round2_package_common_traits() {
let round2_package = samples::round2_package();
check_common_traits_for_type(round2_package);
}

View File

@ -0,0 +1,73 @@
#![cfg(feature = "serde")]
mod helpers;
use frost_ristretto255::SigningKey;
use helpers::samples;
use rand::thread_rng;
fn check_common_traits_for_type<T: Clone + Eq + PartialEq + std::fmt::Debug>(v: T) {
// Make sure can be debug-printed. This also catches if the Debug does not
// have an endless recursion (a popular mistake).
println!("{:?}", v);
// Test Clone and Eq
assert_eq!(v, v.clone());
// Make sure it can be unwrapped in a Result (which requires Debug).
let e: Result<T, ()> = Ok(v.clone());
assert_eq!(v, e.unwrap());
}
#[test]
fn check_signing_key_common_traits() {
let mut rng = thread_rng();
let signing_key = SigningKey::new(&mut rng);
check_common_traits_for_type(signing_key);
}
#[test]
fn check_signing_commitments_common_traits() {
let commitments = samples::signing_commitments();
check_common_traits_for_type(commitments);
}
#[test]
fn check_signing_package_common_traits() {
let signing_package = samples::signing_package();
check_common_traits_for_type(signing_package);
}
#[test]
fn check_signature_share_common_traits() {
let signature_share = samples::signature_share();
check_common_traits_for_type(signature_share);
}
#[test]
fn check_secret_share_common_traits() {
let secret_share = samples::secret_share();
check_common_traits_for_type(secret_share);
}
#[test]
fn check_key_package_common_traits() {
let key_package = samples::key_package();
check_common_traits_for_type(key_package);
}
#[test]
fn check_public_key_package_common_traits() {
let public_key_package = samples::public_key_package();
check_common_traits_for_type(public_key_package);
}
#[test]
fn check_round1_package_common_traits() {
let round1_package = samples::round1_package();
check_common_traits_for_type(round1_package);
}
#[test]
fn check_round2_package_common_traits() {
let round2_package = samples::round2_package();
check_common_traits_for_type(round2_package);
}

View File

@ -0,0 +1,73 @@
#![cfg(feature = "serde")]
mod helpers;
use frost_secp256k1::SigningKey;
use helpers::samples;
use rand::thread_rng;
fn check_common_traits_for_type<T: Clone + Eq + PartialEq + std::fmt::Debug>(v: T) {
// Make sure can be debug-printed. This also catches if the Debug does not
// have an endless recursion (a popular mistake).
println!("{:?}", v);
// Test Clone and Eq
assert_eq!(v, v.clone());
// Make sure it can be unwrapped in a Result (which requires Debug).
let e: Result<T, ()> = Ok(v.clone());
assert_eq!(v, e.unwrap());
}
#[test]
fn check_signing_key_common_traits() {
let mut rng = thread_rng();
let signing_key = SigningKey::new(&mut rng);
check_common_traits_for_type(signing_key);
}
#[test]
fn check_signing_commitments_common_traits() {
let commitments = samples::signing_commitments();
check_common_traits_for_type(commitments);
}
#[test]
fn check_signing_package_common_traits() {
let signing_package = samples::signing_package();
check_common_traits_for_type(signing_package);
}
#[test]
fn check_signature_share_common_traits() {
let signature_share = samples::signature_share();
check_common_traits_for_type(signature_share);
}
#[test]
fn check_secret_share_common_traits() {
let secret_share = samples::secret_share();
check_common_traits_for_type(secret_share);
}
#[test]
fn check_key_package_common_traits() {
let key_package = samples::key_package();
check_common_traits_for_type(key_package);
}
#[test]
fn check_public_key_package_common_traits() {
let public_key_package = samples::public_key_package();
check_common_traits_for_type(public_key_package);
}
#[test]
fn check_round1_package_common_traits() {
let round1_package = samples::round1_package();
check_common_traits_for_type(round1_package);
}
#[test]
fn check_round2_package_common_traits() {
let round2_package = samples::round2_package();
check_common_traits_for_type(round2_package);
}

View File

@ -321,6 +321,7 @@ fn main() -> ExitCode {
"src/tests/coefficient_commitment.rs",
"src/tests/proptests.rs",
"src/tests/vss_commitment.rs",
"tests/common_traits_tests.rs",
"tests/recreation_tests.rs",
"tests/serde_tests.rs",
"tests/helpers/samples.rs",