diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 917a0b2e..b861363d 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -8,6 +8,7 @@ - [Signing](tutorial/signing.md) - [Distributed Key Generation](tutorial/dkg.md) - [User Documentation](user.md) + - [Serialization Format](user/serialization.md) - [FROST with Zcash](zcash.md) - [Technical Details](zcash/technical-details.md) - [Ywallet Demo](zcash/ywallet-demo.md) diff --git a/book/src/tutorial/importing.md b/book/src/tutorial/importing.md index 5ad4d7d8..7420839d 100644 --- a/book/src/tutorial/importing.md +++ b/book/src/tutorial/importing.md @@ -20,9 +20,21 @@ generation or signing procedure. 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: +help with serialization in the following ways: + +### Default byte-oriented serialization + +With the `serialization` feature, which is enabled by default, all structs that +need to communicated will have `serialize()` and `deserialize()` methods. The +serialization format is described in [Serialization +Format](../user/serialization.md). + +### serde + +Alternatively, if you would like to user another format such as JSON, you can +enable the `serde` feature (which is *not* enabled by default). When it is +enabled, you can use [serde](https://serde.rs/) to serialize any structure that +needs to be transmitted. The importing would look like: ``` [dependencies] @@ -33,5 +45,5 @@ 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.) +string encodings; the application can encode those byte strings as it wishes, as +well the structure themselves and things like maps and lists.) diff --git a/book/src/user/serialization.md b/book/src/user/serialization.md new file mode 100644 index 00000000..2c58a75a --- /dev/null +++ b/book/src/user/serialization.md @@ -0,0 +1,60 @@ +# Serialization Format + +With the `serialization` feature, which is enabled by default, all structs that +need to communicated will have `serialize()` and `deserialize()` methods. + +The format is basically the `serde` encoding of the structs using the +[`postcard`](https://docs.rs/postcard/latest/postcard/) crate. + +- Integers are encoded in [varint + format](https://postcard.jamesmunns.com/wire-format#varint-encoded-integers) +- Fixed-size byte arrays are encoded as-is (e.g. scalars, elements) + - Note that the encoding of scalars and elements are defined by the + ciphersuites. +- Variable-size byte arrays are encoded with a length prefix (varint-encoded) + and the array as-is (e.g. the message) +- Maps are encoded as the varint-encoded item count, followed by concatenated + item encodings. +- Ciphersuite IDs are encoded as the 4-byte CRC-32 of the ID string. +- Structs are encoded as the concatenation of the encodings of its items. + +For example, the following Signing Package: + +- Commitments (map): + - Identifier (byte array): `2a00000000000000000000000000000000000000000000000000000000000000` + - Signing Commitments: + - Hiding (byte array): `e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76` + - Bindng (byte array): `6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919` + - Ciphersuite ID: `"FROST(ristretto255, SHA-512)"` +- Message (variable size byte array): `68656c6c6f20776f726c64` (`"hello world"` in UTF-8) +- Ciphersuite ID (4 bytes): `"FROST(ristretto255, SHA-512)"` + +Is encoded as + +``` +012a000000000000000000000000000000000000000000000000000000000000 +00e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d +766a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b9 +19e6811b690b68656c6c6f20776f726c64e6811b69 +``` + +- `01`: the length of the map +- `2a00000000000000000000000000000000000000000000000000000000000000`: the identifier +- `e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76`: the hinding commitment +- `6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919`: the binding commitment +- `e6811b69`: the ciphersuite ID of the SigningCommitments, CRC-32 of "FROST(ristretto255, SHA-512)" +- `0b`: the length of the message +- `68656c6c6f20776f726c64`: the message +- `e6811b69`: the ciphersuite ID of the SigningPackage, CRC-32 of "FROST(ristretto255, SHA-512)" + +```admonish note +The ciphersuite ID is encoded multiple times in this case because `SigningPackage` includes +`SigningCommitments`, which also need to be communicated in Round 1 and thus also encodes +its ciphersuite ID. This is the only instance where this happens. +``` + +## Test Vectors + +Check the +[`snapshots`](https://github.com/search?q=repo%3AZcashFoundation%2Ffrost+path%3Asnapshots&type=code) +files in each ciphersuite crate for test vectors. \ No newline at end of file diff --git a/frost-core/Cargo.toml b/frost-core/Cargo.toml index 6a42ac8c..3efce8b8 100644 --- a/frost-core/Cargo.toml +++ b/frost-core/Cargo.toml @@ -23,10 +23,12 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] byteorder = "1.4" +const-crc32 = "1.2.0" document-features = "0.2.7" debugless-unwrap = "0.0.4" derive-getters = "0.3.0" hex = "0.4.3" +postcard = { version = "1.0.0", features = ["use-std"], optional = true } rand_core = "0.6" serde = { version = "1.0.160", features = ["derive"], optional = true } serdect = { version = "0.2.0", optional = true } @@ -48,7 +50,7 @@ rand_chacha = "0.3" serde_json = "1.0" [features] -default = [] +default = ["serialization"] #! ## Features ## Expose internal types, which do not have SemVer guarantees. This is an advanced ## feature which can be useful if you need to build a modified version of FROST. @@ -58,6 +60,7 @@ internals = [] ## can use `serde` to serialize structs with any encoder that supports ## `serde` (e.g. JSON with `serde_json`). serde = ["dep:serde", "dep:serdect"] +serialization = ["serde", "dep:postcard"] # Exposes ciphersuite-generic tests for other crates to use test-impl = ["proptest", "serde_json", "criterion"] diff --git a/frost-core/src/error.rs b/frost-core/src/error.rs index 86465ecd..0490665b 100644 --- a/frost-core/src/error.rs +++ b/frost-core/src/error.rs @@ -101,6 +101,12 @@ pub enum Error { /// The ciphersuite does not support deriving identifiers from strings. #[error("The ciphersuite does not support deriving identifiers from strings.")] IdentifierDerivationNotSupported, + /// Error serializing value. + #[error("Error serializing value.")] + SerializationError, + /// Error deserializing value. + #[error("Error deserializing value.")] + DeserializationError, } impl Error @@ -147,6 +153,8 @@ where | Error::UnknownIdentifier | Error::IncorrectNumberOfIdentifiers | Error::IncorrectNumberOfCommitments + | Error::SerializationError + | Error::DeserializationError | Error::IdentifierDerivationNotSupported => None, } } diff --git a/frost-core/src/frost.rs b/frost-core/src/frost.rs index f1ea47ef..1909c7d5 100644 --- a/frost-core/src/frost.rs +++ b/frost-core/src/frost.rs @@ -23,8 +23,8 @@ pub mod round1; pub mod round2; use crate::{ - scalar_mul::VartimeMultiscalarMul, Ciphersuite, Element, Error, Field, Group, Scalar, - Signature, VerifyingKey, + scalar_mul::VartimeMultiscalarMul, Ciphersuite, Deserialize, Element, Error, Field, Group, + Scalar, Serialize, Signature, VerifyingKey, }; pub use self::identifier::Identifier; @@ -306,6 +306,22 @@ where } } +#[cfg(feature = "serialization")] +impl SigningPackage +where + C: Ciphersuite + serde::Serialize + for<'de> serde::Deserialize<'de>, +{ + /// Serialize the struct into a Vec. + pub fn serialize(&self) -> Result, Error> { + Serialize::serialize(&self) + } + + /// Deserialize the struct from a slice of bytes. + pub fn deserialize(bytes: &[u8]) -> Result> { + Deserialize::deserialize(bytes) + } +} + /// The product of all signers' individual commitments, published as part of the /// final signature. #[derive(Clone, PartialEq, Eq)] diff --git a/frost-core/src/frost/keys.rs b/frost-core/src/frost/keys.rs index 7f21646e..85ecb877 100644 --- a/frost-core/src/frost/keys.rs +++ b/frost-core/src/frost/keys.rs @@ -17,7 +17,8 @@ use rand_core::{CryptoRng, RngCore}; use zeroize::{DefaultIsZeroes, Zeroize}; use crate::{ - frost::Identifier, Ciphersuite, Element, Error, Field, Group, Scalar, SigningKey, VerifyingKey, + frost::Identifier, Ciphersuite, Deserialize, Element, Error, Field, Group, Scalar, Serialize, + SigningKey, VerifyingKey, }; #[cfg(feature = "serde")] @@ -425,6 +426,22 @@ where } } +#[cfg(feature = "serialization")] +impl SecretShare +where + C: Ciphersuite + serde::Serialize + for<'de> serde::Deserialize<'de>, +{ + /// Serialize the struct into a Vec. + pub fn serialize(&self) -> Result, Error> { + Serialize::serialize(&self) + } + + /// Deserialize the struct from a slice of bytes. + pub fn deserialize(bytes: &[u8]) -> Result> { + Deserialize::deserialize(bytes) + } +} + /// The identifier list to use when generating key shares. pub enum IdentifierList<'a, C: Ciphersuite> { /// Use the default values (1 to max_signers, inclusive). @@ -613,6 +630,22 @@ where } } +#[cfg(feature = "serialization")] +impl KeyPackage +where + C: Ciphersuite + serde::Serialize + for<'de> serde::Deserialize<'de>, +{ + /// Serialize the struct into a Vec. + pub fn serialize(&self) -> Result, Error> { + Serialize::serialize(&self) + } + + /// Deserialize the struct from a slice of bytes. + pub fn deserialize(bytes: &[u8]) -> Result> { + Deserialize::deserialize(bytes) + } +} + impl TryFrom> for KeyPackage where C: Ciphersuite, @@ -684,6 +717,22 @@ where } } +#[cfg(feature = "serialization")] +impl PublicKeyPackage +where + C: Ciphersuite + serde::Serialize + for<'de> serde::Deserialize<'de>, +{ + /// Serialize the struct into a Vec. + pub fn serialize(&self) -> Result, Error> { + Serialize::serialize(&self) + } + + /// Deserialize the struct from a slice of bytes. + pub fn deserialize(bytes: &[u8]) -> Result> { + Deserialize::deserialize(bytes) + } +} + fn validate_num_of_signers( min_signers: u16, max_signers: u16, diff --git a/frost-core/src/frost/keys/dkg.rs b/frost-core/src/frost/keys/dkg.rs index 5f98c9f7..1269e373 100644 --- a/frost-core/src/frost/keys/dkg.rs +++ b/frost-core/src/frost/keys/dkg.rs @@ -50,6 +50,8 @@ pub mod round1 { use derive_getters::Getters; use zeroize::Zeroize; + use crate::{Deserialize, Serialize}; + use super::*; /// The package that must be broadcast by each participant to all other participants @@ -92,6 +94,22 @@ pub mod round1 { } } + #[cfg(feature = "serialization")] + impl Package + where + C: Ciphersuite + serde::Serialize + for<'de> serde::Deserialize<'de>, + { + /// Serialize the struct into a Vec. + pub fn serialize(&self) -> Result, Error> { + Serialize::serialize(&self) + } + + /// Deserialize the struct from a slice of bytes. + pub fn deserialize(bytes: &[u8]) -> Result> { + Deserialize::deserialize(bytes) + } + } + /// The secret package that must be kept in memory by the participant /// between the first and second parts of the DKG protocol (round 1). /// @@ -145,6 +163,8 @@ pub mod round2 { use derive_getters::Getters; use zeroize::Zeroize; + use crate::{Deserialize, Serialize}; + use super::*; /// A package that must be sent by each participant to some other participants @@ -186,6 +206,22 @@ pub mod round2 { } } + #[cfg(feature = "serialization")] + impl Package + where + C: Ciphersuite + serde::Serialize + for<'de> serde::Deserialize<'de>, + { + /// Serialize the struct into a Vec. + pub fn serialize(&self) -> Result, Error> { + Serialize::serialize(&self) + } + + /// Deserialize the struct from a slice of bytes. + pub fn deserialize(bytes: &[u8]) -> Result> { + Deserialize::deserialize(bytes) + } + } + /// The secret package that must be kept in memory by the participant /// between the second and third parts of the DKG protocol (round 2). /// diff --git a/frost-core/src/frost/round1.rs b/frost-core/src/frost/round1.rs index 7ce34c20..670ab147 100644 --- a/frost-core/src/frost/round1.rs +++ b/frost-core/src/frost/round1.rs @@ -12,7 +12,7 @@ use hex::FromHex; use rand_core::{CryptoRng, RngCore}; use zeroize::Zeroize; -use crate::{frost, Ciphersuite, Element, Error, Field, Group, Scalar}; +use crate::{frost, Ciphersuite, Deserialize, Element, Error, Field, Group, Scalar, Serialize}; #[cfg(feature = "serde")] use crate::ElementSerialization; @@ -311,6 +311,22 @@ where } } +#[cfg(feature = "serialization")] +impl SigningCommitments +where + C: Ciphersuite + serde::Serialize + for<'de> serde::Deserialize<'de>, +{ + /// Serialize the struct into a Vec. + pub fn serialize(&self) -> Result, Error> { + Serialize::serialize(&self) + } + + /// Deserialize the struct from a slice of bytes. + pub fn deserialize(bytes: &[u8]) -> Result> { + Deserialize::deserialize(bytes) + } +} + impl From<&SigningNonces> for SigningCommitments where C: Ciphersuite, diff --git a/frost-core/src/lib.rs b/frost-core/src/lib.rs index de02aaa5..d01d6151 100644 --- a/frost-core/src/lib.rs +++ b/frost-core/src/lib.rs @@ -116,7 +116,7 @@ where where S: serde::Serializer, { - serdect::slice::serialize_hex_lower_or_bin(&self.0.as_ref(), serializer) + serdect::array::serialize_hex_lower_or_bin(&self.0.as_ref(), serializer) } } @@ -129,7 +129,14 @@ where where D: serde::Deserializer<'de>, { - let bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?; + // Get size from the size of the zero scalar + let zero = <::Field as Field>::zero(); + let len = <::Field as Field>::serialize(&zero) + .as_ref() + .len(); + + let mut bytes = vec![0u8; len]; + serdect::array::deserialize_hex_or_bin(&mut bytes[..], deserializer)?; let array = bytes .try_into() .map_err(|_| serde::de::Error::custom("invalid byte length"))?; @@ -214,7 +221,7 @@ where where S: serde::Serializer, { - serdect::slice::serialize_hex_lower_or_bin(&self.0.as_ref(), serializer) + serdect::array::serialize_hex_lower_or_bin(&self.0.as_ref(), serializer) } } @@ -227,7 +234,12 @@ where where D: serde::Deserializer<'de>, { - let bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?; + // Get size from the size of the generator + let generator = ::generator(); + let len = ::serialize(&generator).as_ref().len(); + + let mut bytes = vec![0u8; len]; + serdect::array::deserialize_hex_or_bin(&mut bytes[..], deserializer)?; let array = bytes .try_into() .map_err(|_| serde::de::Error::custom("invalid byte length"))?; @@ -330,6 +342,15 @@ pub trait Ciphersuite: Copy + Clone + PartialEq + Debug { } } +// The short 4-byte ID. Derived as the CRC-32 of the UTF-8 +// encoded ID in big endian format. +const fn short_id() -> [u8; 4] +where + C: Ciphersuite, +{ + const_crc32::crc32(C::ID.as_bytes()).to_be_bytes() +} + /// A type refinement for the scalar field element representing the per-message _[challenge]_. /// /// [challenge]: https://www.ietf.org/archive/id/draft-irtf-cfrg-frost-14.html#name-signature-challenge-computa @@ -412,7 +433,13 @@ where S: serde::Serializer, C: Ciphersuite, { - s.serialize_str(C::ID) + use serde::Serialize; + + if s.is_human_readable() { + C::ID.serialize(s) + } else { + serde::Serialize::serialize(&short_id::(), s) + } } /// Deserialize a placeholder ciphersuite field, checking if it's the ciphersuite ID string. @@ -422,10 +449,55 @@ where D: serde::Deserializer<'de>, C: Ciphersuite, { - let s: &str = serde::de::Deserialize::deserialize(deserializer)?; - if s != C::ID { - Err(serde::de::Error::custom("wrong ciphersuite")) + if deserializer.is_human_readable() { + let s: &str = serde::de::Deserialize::deserialize(deserializer)?; + if s != C::ID { + Err(serde::de::Error::custom("wrong ciphersuite")) + } else { + Ok(()) + } } else { - Ok(()) + let buffer: [u8; 4] = serde::de::Deserialize::deserialize(deserializer)?; + if buffer != short_id::() { + Err(serde::de::Error::custom("wrong ciphersuite")) + } else { + Ok(()) + } + } +} + +// Default byte-oriented serialization for structs that need to be communicated. +// +// Note that we still manually implement these methods in each applicable type, +// instead of making these traits `pub` and asking users to import the traits. +// The reason is that ciphersuite traits would need to re-export these traits, +// parametrized with the ciphersuite, but trait aliases are not currently +// supported: + +#[cfg(feature = "serialization")] +trait Serialize { + /// Serialize the struct into a Vec. + fn serialize(&self) -> Result, Error>; +} + +#[cfg(feature = "serialization")] +trait Deserialize { + /// Deserialize the struct from a slice of bytes. + fn deserialize(bytes: &[u8]) -> Result> + where + Self: std::marker::Sized; +} + +#[cfg(feature = "serialization")] +impl Serialize for T { + fn serialize(&self) -> Result, Error> { + postcard::to_stdvec(self).map_err(|_| Error::SerializationError) + } +} + +#[cfg(feature = "serialization")] +impl serde::Deserialize<'de>, C: Ciphersuite> Deserialize for T { + fn deserialize(bytes: &[u8]) -> Result> { + postcard::from_bytes(bytes).map_err(|_| Error::DeserializationError) } } diff --git a/frost-ed25519/Cargo.toml b/frost-ed25519/Cargo.toml index 1be619f1..f0e9e125 100644 --- a/frost-ed25519/Cargo.toml +++ b/frost-ed25519/Cargo.toml @@ -34,6 +34,7 @@ criterion = "0.5" frost-core = { path = "../frost-core", version = "0.6.0", features = ["test-impl"] } frost-rerandomized = { path = "../frost-rerandomized", version = "0.6.0", features = ["test-impl"] } ed25519-dalek = "2.0.0" +insta = { version = "1.31.0", features = ["yaml"] } hex = "0.4.3" lazy_static = "1.4" proptest = "1.0" @@ -43,7 +44,8 @@ serde_json = "1.0" [features] nightly = [] -default = [] +default = ["serialization"] +serialization = ["serde", "frost-core/serialization"] #! ## Features ## Enable `serde` support for types that need to be communicated. You ## can use `serde` to serialize structs with any encoder that supports diff --git a/frost-ed25519/tests/serialization_tests.rs b/frost-ed25519/tests/serialization_tests.rs new file mode 100644 index 00000000..424406b5 --- /dev/null +++ b/frost-ed25519/tests/serialization_tests.rs @@ -0,0 +1,94 @@ +#![cfg(feature = "serialization")] + +mod helpers; + +use frost_ed25519::{ + keys::{ + dkg::{round1, round2}, + KeyPackage, PublicKeyPackage, SecretShare, + }, + round1::SigningCommitments, + round2::SignatureShare, + SigningPackage, +}; + +use helpers::samples; +use insta::assert_snapshot; + +#[test] +fn check_signing_commitments_postcard_serialization() { + let commitments = samples::signing_commitments(); + let bytes: Vec<_> = commitments.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + commitments, + SigningCommitments::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_signing_package_postcard_serialization() { + let signing_package = samples::signing_package(); + let bytes: Vec<_> = signing_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + signing_package, + SigningPackage::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_signature_share_postcard_serialization() { + let signature_share = samples::signature_share(); + let bytes = signature_share.serialize(); + assert_snapshot!(hex::encode(bytes)); + assert_eq!(signature_share, SignatureShare::deserialize(bytes).unwrap()); +} +#[test] +fn check_secret_share_postcard_serialization() { + let secret_share = samples::secret_share(); + let bytes: Vec<_> = secret_share.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!(secret_share, SecretShare::deserialize(&bytes).unwrap()); +} + +#[test] +fn check_key_package_postcard_serialization() { + let key_package = samples::key_package(); + let bytes: Vec<_> = key_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!(key_package, KeyPackage::deserialize(&bytes).unwrap()); +} + +#[test] +fn check_public_key_package_postcard_serialization() { + let public_key_package = samples::public_key_package(); + let bytes: Vec<_> = public_key_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + public_key_package, + PublicKeyPackage::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_round1_package_postcard_serialization() { + let round1_package = samples::round1_package(); + let bytes: Vec<_> = round1_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + round1_package, + round1::Package::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_round2_package_postcard_serialization() { + let round2_package = samples::round2_package(); + let bytes: Vec<_> = round2_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + round2_package, + round2::Package::deserialize(&bytes).unwrap() + ); +} diff --git a/frost-ed25519/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap b/frost-ed25519/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap new file mode 100644 index 00000000..2638eaa8 --- /dev/null +++ b/frost-ed25519/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed25519/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +2a00000000000000000000000000000000000000000000000000000000000000498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a5866666666666666666666666666666666666666666666666666666666666666586666666666666666666666666666666666666666666666666666666666666602ea38536e diff --git a/frost-ed25519/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap b/frost-ed25519/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap new file mode 100644 index 00000000..2e0e8071 --- /dev/null +++ b/frost-ed25519/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed25519/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +012a0000000000000000000000000000000000000000000000000000000000000058666666666666666666666666666666666666666666666666666666666666665866666666666666666666666666666666666666666666666666666666666666ea38536e diff --git a/frost-ed25519/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap b/frost-ed25519/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap new file mode 100644 index 00000000..a25f9473 --- /dev/null +++ b/frost-ed25519/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed25519/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +015866666666666666666666666666666666666666666666666666666666666666405866666666666666666666666666666666666666666666666666666666666666498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0aea38536e diff --git a/frost-ed25519/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap b/frost-ed25519/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap new file mode 100644 index 00000000..65e4605a --- /dev/null +++ b/frost-ed25519/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed25519/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0aea38536e diff --git a/frost-ed25519/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap b/frost-ed25519/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap new file mode 100644 index 00000000..a51399e0 --- /dev/null +++ b/frost-ed25519/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed25519/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +2a00000000000000000000000000000000000000000000000000000000000000498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a015866666666666666666666666666666666666666666666666666666666666666ea38536e diff --git a/frost-ed25519/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap b/frost-ed25519/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap new file mode 100644 index 00000000..ef05a370 --- /dev/null +++ b/frost-ed25519/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed25519/tests/serialization_tests.rs +expression: "hex::encode(bytes)" +--- +498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a diff --git a/frost-ed25519/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap b/frost-ed25519/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap new file mode 100644 index 00000000..5d5abecf --- /dev/null +++ b/frost-ed25519/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed25519/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +5866666666666666666666666666666666666666666666666666666666666666c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022ea38536e diff --git a/frost-ed25519/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap b/frost-ed25519/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap new file mode 100644 index 00000000..0aedfbf0 --- /dev/null +++ b/frost-ed25519/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed25519/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +012a000000000000000000000000000000000000000000000000000000000000005866666666666666666666666666666666666666666666666666666666666666c9a3f86aae465f0e56513864510f3997561fa2c9e85ea21dc2292309f3cd6022ea38536e0b68656c6c6f20776f726c64ea38536e diff --git a/frost-ed448/Cargo.toml b/frost-ed448/Cargo.toml index 32ef2305..e915a683 100644 --- a/frost-ed448/Cargo.toml +++ b/frost-ed448/Cargo.toml @@ -33,6 +33,7 @@ criterion = "0.5" frost-core = { path = "../frost-core", version = "0.6.0", features = ["test-impl"] } frost-rerandomized = { path = "../frost-rerandomized", version = "0.6.0", features = ["test-impl"] } lazy_static = "1.4" +insta = { version = "1.31.0", features = ["yaml"] } hex = "0.4.3" proptest = "1.0" rand = "0.8" @@ -41,7 +42,8 @@ serde_json = "1.0" [features] nightly = [] -default = [] +default = ["serialization"] +serialization = ["serde", "frost-core/serialization"] #! ## Features ## Enable `serde` support for types that need to be communicated. You ## can use `serde` to serialize structs with any encoder that supports diff --git a/frost-ed448/tests/serialization_tests.rs b/frost-ed448/tests/serialization_tests.rs new file mode 100644 index 00000000..21cc36ce --- /dev/null +++ b/frost-ed448/tests/serialization_tests.rs @@ -0,0 +1,94 @@ +#![cfg(feature = "serialization")] + +mod helpers; + +use frost_ed448::{ + keys::{ + dkg::{round1, round2}, + KeyPackage, PublicKeyPackage, SecretShare, + }, + round1::SigningCommitments, + round2::SignatureShare, + SigningPackage, +}; + +use helpers::samples; +use insta::assert_snapshot; + +#[test] +fn check_signing_commitments_postcard_serialization() { + let commitments = samples::signing_commitments(); + let bytes: Vec<_> = commitments.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + commitments, + SigningCommitments::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_signing_package_postcard_serialization() { + let signing_package = samples::signing_package(); + let bytes: Vec<_> = signing_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + signing_package, + SigningPackage::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_signature_share_postcard_serialization() { + let signature_share = samples::signature_share(); + let bytes = signature_share.serialize(); + assert_snapshot!(hex::encode(bytes)); + assert_eq!(signature_share, SignatureShare::deserialize(bytes).unwrap()); +} +#[test] +fn check_secret_share_postcard_serialization() { + let secret_share = samples::secret_share(); + let bytes: Vec<_> = secret_share.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!(secret_share, SecretShare::deserialize(&bytes).unwrap()); +} + +#[test] +fn check_key_package_postcard_serialization() { + let key_package = samples::key_package(); + let bytes: Vec<_> = key_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!(key_package, KeyPackage::deserialize(&bytes).unwrap()); +} + +#[test] +fn check_public_key_package_postcard_serialization() { + let public_key_package = samples::public_key_package(); + let bytes: Vec<_> = public_key_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + public_key_package, + PublicKeyPackage::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_round1_package_postcard_serialization() { + let round1_package = samples::round1_package(); + let bytes: Vec<_> = round1_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + round1_package, + round1::Package::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_round2_package_postcard_serialization() { + let round2_package = samples::round2_package(); + let bytes: Vec<_> = round2_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + round2_package, + round2::Package::deserialize(&bytes).unwrap() + ); +} diff --git a/frost-ed448/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap b/frost-ed448/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap new file mode 100644 index 00000000..54f54937 --- /dev/null +++ b/frost-ed448/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed448/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +2a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a0014fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f690014fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f690002854361d9 diff --git a/frost-ed448/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap b/frost-ed448/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap new file mode 100644 index 00000000..51ceb6ae --- /dev/null +++ b/frost-ed448/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed448/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +012a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f690014fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900854361d9 diff --git a/frost-ed448/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap b/frost-ed448/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap new file mode 100644 index 00000000..6785b8c5 --- /dev/null +++ b/frost-ed448/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed448/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +0114fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f69007214fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f69004d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00854361d9 diff --git a/frost-ed448/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap b/frost-ed448/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap new file mode 100644 index 00000000..ea338296 --- /dev/null +++ b/frost-ed448/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed448/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00854361d9 diff --git a/frost-ed448/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap b/frost-ed448/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap new file mode 100644 index 00000000..309aeb25 --- /dev/null +++ b/frost-ed448/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed448/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +2a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a000114fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900854361d9 diff --git a/frost-ed448/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap b/frost-ed448/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap new file mode 100644 index 00000000..3b9fcbc7 --- /dev/null +++ b/frost-ed448/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed448/tests/serialization_tests.rs +expression: "hex::encode(bytes)" +--- +4d83e51cb78150c2380ad9b3a18148166024e4c9db3cdf82466d3153aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2a00 diff --git a/frost-ed448/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap b/frost-ed448/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap new file mode 100644 index 00000000..6028dc0e --- /dev/null +++ b/frost-ed448/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed448/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +14fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80854361d9 diff --git a/frost-ed448/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap b/frost-ed448/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap new file mode 100644 index 00000000..8c000a38 --- /dev/null +++ b/frost-ed448/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ed448/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +012a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014fa30f25b790898adc8d74e2c13bdfdc4397ce61cffd33ad7c2a0051e9c78874098a36c7373ea4b62c7c9563720768824bcb66e71463f6900ed8693eacdfbeada6ba0cdd1beb2bcbb98302a3a8365650db8c4d88a726de3b7d74d8835a0d76e03b0c2865020d659b38d04d74a63e905ae80854361d90b68656c6c6f20776f726c64854361d9 diff --git a/frost-p256/Cargo.toml b/frost-p256/Cargo.toml index 36c60847..1ba43e41 100644 --- a/frost-p256/Cargo.toml +++ b/frost-p256/Cargo.toml @@ -33,6 +33,7 @@ sha2 = "0.10.2" criterion = "0.5" frost-core = { path = "../frost-core", version = "0.6.0", features = ["test-impl"] } frost-rerandomized = { path = "../frost-rerandomized", version = "0.6.0", features = ["test-impl"] } +insta = { version = "1.31.0", features = ["yaml"] } hex = "0.4.3" lazy_static = "1.4" proptest = "1.0" @@ -42,7 +43,8 @@ serde_json = "1.0" [features] nightly = [] -default = [] +default = ["serialization"] +serialization = ["serde", "frost-core/serialization"] #! ## Features ## Enable `serde` support for types that need to be communicated. You ## can use `serde` to serialize structs with any encoder that supports diff --git a/frost-p256/tests/serialization_tests.rs b/frost-p256/tests/serialization_tests.rs new file mode 100644 index 00000000..49a95491 --- /dev/null +++ b/frost-p256/tests/serialization_tests.rs @@ -0,0 +1,94 @@ +#![cfg(feature = "serialization")] + +mod helpers; + +use frost_p256::{ + keys::{ + dkg::{round1, round2}, + KeyPackage, PublicKeyPackage, SecretShare, + }, + round1::SigningCommitments, + round2::SignatureShare, + SigningPackage, +}; + +use helpers::samples; +use insta::assert_snapshot; + +#[test] +fn check_signing_commitments_postcard_serialization() { + let commitments = samples::signing_commitments(); + let bytes: Vec<_> = commitments.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + commitments, + SigningCommitments::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_signing_package_postcard_serialization() { + let signing_package = samples::signing_package(); + let bytes: Vec<_> = signing_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + signing_package, + SigningPackage::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_signature_share_postcard_serialization() { + let signature_share = samples::signature_share(); + let bytes = signature_share.serialize(); + assert_snapshot!(hex::encode(bytes)); + assert_eq!(signature_share, SignatureShare::deserialize(bytes).unwrap()); +} +#[test] +fn check_secret_share_postcard_serialization() { + let secret_share = samples::secret_share(); + let bytes: Vec<_> = secret_share.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!(secret_share, SecretShare::deserialize(&bytes).unwrap()); +} + +#[test] +fn check_key_package_postcard_serialization() { + let key_package = samples::key_package(); + let bytes: Vec<_> = key_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!(key_package, KeyPackage::deserialize(&bytes).unwrap()); +} + +#[test] +fn check_public_key_package_postcard_serialization() { + let public_key_package = samples::public_key_package(); + let bytes: Vec<_> = public_key_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + public_key_package, + PublicKeyPackage::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_round1_package_postcard_serialization() { + let round1_package = samples::round1_package(); + let bytes: Vec<_> = round1_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + round1_package, + round1::Package::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_round2_package_postcard_serialization() { + let round2_package = samples::round2_package(); + let bytes: Vec<_> = round2_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + round2_package, + round2::Package::deserialize(&bytes).unwrap() + ); +} diff --git a/frost-p256/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap b/frost-p256/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap new file mode 100644 index 00000000..b8767051 --- /dev/null +++ b/frost-p256/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-p256/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +000000000000000000000000000000000000000000000000000000000000002aaaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296029bf7b2e7 diff --git a/frost-p256/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap b/frost-p256/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap new file mode 100644 index 00000000..f7d9a942 --- /dev/null +++ b/frost-p256/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-p256/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +01000000000000000000000000000000000000000000000000000000000000002a036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2969bf7b2e7 diff --git a/frost-p256/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap b/frost-p256/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap new file mode 100644 index 00000000..4b45ec7f --- /dev/null +++ b/frost-p256/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-p256/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +01036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c29641036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e19bf7b2e7 diff --git a/frost-p256/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap b/frost-p256/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap new file mode 100644 index 00000000..722deee8 --- /dev/null +++ b/frost-p256/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-p256/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e19bf7b2e7 diff --git a/frost-p256/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap b/frost-p256/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap new file mode 100644 index 00000000..8fb3a3b9 --- /dev/null +++ b/frost-p256/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-p256/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +000000000000000000000000000000000000000000000000000000000000002aaaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e101036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2969bf7b2e7 diff --git a/frost-p256/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap b/frost-p256/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap new file mode 100644 index 00000000..8ec63ca8 --- /dev/null +++ b/frost-p256/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-p256/tests/serialization_tests.rs +expression: "hex::encode(bytes)" +--- +aaaaaaaa00000000aaaaaaaaaaaaaaaa7def51c91a0fbf034d26872ca84218e1 diff --git a/frost-p256/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap b/frost-p256/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap new file mode 100644 index 00000000..f6153632 --- /dev/null +++ b/frost-p256/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-p256/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc476699789bf7b2e7 diff --git a/frost-p256/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap b/frost-p256/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap new file mode 100644 index 00000000..0bd2d333 --- /dev/null +++ b/frost-p256/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-p256/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +01000000000000000000000000000000000000000000000000000000000000002a036b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296037cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc476699789bf7b2e70b68656c6c6f20776f726c649bf7b2e7 diff --git a/frost-rerandomized/Cargo.toml b/frost-rerandomized/Cargo.toml index 7fabf5fd..bf32d7df 100644 --- a/frost-rerandomized/Cargo.toml +++ b/frost-rerandomized/Cargo.toml @@ -29,7 +29,8 @@ rand_core = "0.6" [features] nightly = [] -default = [] +default = ["serialization"] +serialization = ["serde", "frost-core/serialization"] #! ## Features ## Enable `serde` support for types that need to be communicated. You ## can use `serde` to serialize structs with any encoder that supports diff --git a/frost-ristretto255/Cargo.toml b/frost-ristretto255/Cargo.toml index 64f14e85..a4a0987d 100644 --- a/frost-ristretto255/Cargo.toml +++ b/frost-ristretto255/Cargo.toml @@ -29,8 +29,10 @@ sha2 = "0.10.2" criterion = { version = "0.5", features = ["html_reports"] } frost-core = { path = "../frost-core", version = "0.6.0", features = ["test-impl"] } frost-rerandomized = { path = "../frost-rerandomized", version = "0.6.0", features = ["test-impl"] } +insta = { version = "1.31.0", features = ["yaml"] } hex = "0.4.3" lazy_static = "1.4" +postcard = { version = "1.0.0", features = ["use-std"] } proptest = "1.0" rand = "0.8" rand_chacha = "0.3" @@ -38,7 +40,8 @@ serde_json = "1.0" [features] nightly = [] -default = [] +default = ["serialization"] +serialization = ["serde", "frost-core/serialization"] #! ## Features ## Enable `serde` support for types that need to be communicated. You ## can use `serde` to serialize structs with any encoder that supports diff --git a/frost-ristretto255/tests/serialization_tests.rs b/frost-ristretto255/tests/serialization_tests.rs new file mode 100644 index 00000000..f59d5213 --- /dev/null +++ b/frost-ristretto255/tests/serialization_tests.rs @@ -0,0 +1,94 @@ +#![cfg(feature = "serialization")] + +mod helpers; + +use frost_ristretto255::{ + keys::{ + dkg::{round1, round2}, + KeyPackage, PublicKeyPackage, SecretShare, + }, + round1::SigningCommitments, + round2::SignatureShare, + SigningPackage, +}; + +use helpers::samples; +use insta::assert_snapshot; + +#[test] +fn check_signing_commitments_postcard_serialization() { + let commitments = samples::signing_commitments(); + let bytes: Vec<_> = commitments.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + commitments, + SigningCommitments::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_signing_package_postcard_serialization() { + let signing_package = samples::signing_package(); + let bytes: Vec<_> = signing_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + signing_package, + SigningPackage::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_signature_share_postcard_serialization() { + let signature_share = samples::signature_share(); + let bytes = signature_share.serialize(); + assert_snapshot!(hex::encode(bytes)); + assert_eq!(signature_share, SignatureShare::deserialize(bytes).unwrap()); +} +#[test] +fn check_secret_share_postcard_serialization() { + let secret_share = samples::secret_share(); + let bytes: Vec<_> = secret_share.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!(secret_share, SecretShare::deserialize(&bytes).unwrap()); +} + +#[test] +fn check_key_package_postcard_serialization() { + let key_package = samples::key_package(); + let bytes: Vec<_> = key_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!(key_package, KeyPackage::deserialize(&bytes).unwrap()); +} + +#[test] +fn check_public_key_package_postcard_serialization() { + let public_key_package = samples::public_key_package(); + let bytes: Vec<_> = public_key_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + public_key_package, + PublicKeyPackage::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_round1_package_postcard_serialization() { + let round1_package = samples::round1_package(); + let bytes: Vec<_> = round1_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + round1_package, + round1::Package::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_round2_package_postcard_serialization() { + let round2_package = samples::round2_package(); + let bytes: Vec<_> = round2_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + round2_package, + round2::Package::deserialize(&bytes).unwrap() + ); +} diff --git a/frost-ristretto255/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap b/frost-ristretto255/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap new file mode 100644 index 00000000..a465e77c --- /dev/null +++ b/frost-ristretto255/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ristretto255/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +2a00000000000000000000000000000000000000000000000000000000000000498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0ae2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d7602e6811b69 diff --git a/frost-ristretto255/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap b/frost-ristretto255/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap new file mode 100644 index 00000000..67849265 --- /dev/null +++ b/frost-ristretto255/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ristretto255/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +012a00000000000000000000000000000000000000000000000000000000000000e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76e6811b69 diff --git a/frost-ristretto255/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap b/frost-ristretto255/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap new file mode 100644 index 00000000..7591b845 --- /dev/null +++ b/frost-ristretto255/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ristretto255/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +01e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d7640e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0ae6811b69 diff --git a/frost-ristretto255/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap b/frost-ristretto255/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap new file mode 100644 index 00000000..100829cd --- /dev/null +++ b/frost-ristretto255/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ristretto255/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0ae6811b69 diff --git a/frost-ristretto255/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap b/frost-ristretto255/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap new file mode 100644 index 00000000..d49ee757 --- /dev/null +++ b/frost-ristretto255/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ristretto255/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +2a00000000000000000000000000000000000000000000000000000000000000498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a01e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76e6811b69 diff --git a/frost-ristretto255/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap b/frost-ristretto255/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap new file mode 100644 index 00000000..baafb932 --- /dev/null +++ b/frost-ristretto255/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ristretto255/tests/serialization_tests.rs +expression: "hex::encode(bytes)" +--- +498d4e9311420c903913a56c94a694b8aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a diff --git a/frost-ristretto255/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap b/frost-ristretto255/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap new file mode 100644 index 00000000..e6083084 --- /dev/null +++ b/frost-ristretto255/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ristretto255/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d766a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919e6811b69 diff --git a/frost-ristretto255/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap b/frost-ristretto255/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap new file mode 100644 index 00000000..9808c465 --- /dev/null +++ b/frost-ristretto255/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-ristretto255/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +012a00000000000000000000000000000000000000000000000000000000000000e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d766a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919e6811b690b68656c6c6f20776f726c64e6811b69 diff --git a/frost-secp256k1/Cargo.toml b/frost-secp256k1/Cargo.toml index 5ddc5c60..51bce979 100644 --- a/frost-secp256k1/Cargo.toml +++ b/frost-secp256k1/Cargo.toml @@ -32,6 +32,7 @@ sha2 = "0.10.2" criterion = "0.5" frost-core = { path = "../frost-core", version = "0.6.0", features = ["test-impl"] } frost-rerandomized = { path = "../frost-rerandomized", version = "0.6.0", features = ["test-impl"] } +insta = { version = "1.31.0", features = ["yaml"] } hex = "0.4.3" lazy_static = "1.4" proptest = "1.0" @@ -41,7 +42,8 @@ serde_json = "1.0" [features] nightly = [] -default = [] +default = ["serialization"] +serialization = ["serde", "frost-core/serialization"] #! ## Features ## Enable `serde` support for types that need to be communicated. You ## can use `serde` to serialize structs with any encoder that supports diff --git a/frost-secp256k1/tests/serialization_tests.rs b/frost-secp256k1/tests/serialization_tests.rs new file mode 100644 index 00000000..aeb64edf --- /dev/null +++ b/frost-secp256k1/tests/serialization_tests.rs @@ -0,0 +1,94 @@ +#![cfg(feature = "serialization")] + +mod helpers; + +use frost_secp256k1::{ + keys::{ + dkg::{round1, round2}, + KeyPackage, PublicKeyPackage, SecretShare, + }, + round1::SigningCommitments, + round2::SignatureShare, + SigningPackage, +}; + +use helpers::samples; +use insta::assert_snapshot; + +#[test] +fn check_signing_commitments_postcard_serialization() { + let commitments = samples::signing_commitments(); + let bytes: Vec<_> = commitments.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + commitments, + SigningCommitments::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_signing_package_postcard_serialization() { + let signing_package = samples::signing_package(); + let bytes: Vec<_> = signing_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + signing_package, + SigningPackage::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_signature_share_postcard_serialization() { + let signature_share = samples::signature_share(); + let bytes = signature_share.serialize(); + assert_snapshot!(hex::encode(bytes)); + assert_eq!(signature_share, SignatureShare::deserialize(bytes).unwrap()); +} +#[test] +fn check_secret_share_postcard_serialization() { + let secret_share = samples::secret_share(); + let bytes: Vec<_> = secret_share.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!(secret_share, SecretShare::deserialize(&bytes).unwrap()); +} + +#[test] +fn check_key_package_postcard_serialization() { + let key_package = samples::key_package(); + let bytes: Vec<_> = key_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!(key_package, KeyPackage::deserialize(&bytes).unwrap()); +} + +#[test] +fn check_public_key_package_postcard_serialization() { + let public_key_package = samples::public_key_package(); + let bytes: Vec<_> = public_key_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + public_key_package, + PublicKeyPackage::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_round1_package_postcard_serialization() { + let round1_package = samples::round1_package(); + let bytes: Vec<_> = round1_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + round1_package, + round1::Package::deserialize(&bytes).unwrap() + ); +} + +#[test] +fn check_round2_package_postcard_serialization() { + let round2_package = samples::round2_package(); + let bytes: Vec<_> = round2_package.serialize().unwrap(); + assert_snapshot!(hex::encode(&bytes)); + assert_eq!( + round2_package, + round2::Package::deserialize(&bytes).unwrap() + ); +} diff --git a/frost-secp256k1/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap b/frost-secp256k1/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap new file mode 100644 index 00000000..41fcac1d --- /dev/null +++ b/frost-secp256k1/tests/snapshots/serialization_tests__check_key_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-secp256k1/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +000000000000000000000000000000000000000000000000000000000000002aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b810279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817980279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179802f49d8cce diff --git a/frost-secp256k1/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap b/frost-secp256k1/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap new file mode 100644 index 00000000..d40a685a --- /dev/null +++ b/frost-secp256k1/tests/snapshots/serialization_tests__check_public_key_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-secp256k1/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +01000000000000000000000000000000000000000000000000000000000000002a0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f817980279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798f49d8cce diff --git a/frost-secp256k1/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap b/frost-secp256k1/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap new file mode 100644 index 00000000..b17b34f7 --- /dev/null +++ b/frost-secp256k1/tests/snapshots/serialization_tests__check_round1_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-secp256k1/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +010279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798410279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81f49d8cce diff --git a/frost-secp256k1/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap b/frost-secp256k1/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap new file mode 100644 index 00000000..3d368a8e --- /dev/null +++ b/frost-secp256k1/tests/snapshots/serialization_tests__check_round2_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-secp256k1/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81f49d8cce diff --git a/frost-secp256k1/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap b/frost-secp256k1/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap new file mode 100644 index 00000000..fd4d21c6 --- /dev/null +++ b/frost-secp256k1/tests/snapshots/serialization_tests__check_secret_share_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-secp256k1/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +000000000000000000000000000000000000000000000000000000000000002aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81010279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798f49d8cce diff --git a/frost-secp256k1/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap b/frost-secp256k1/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap new file mode 100644 index 00000000..0d3ad555 --- /dev/null +++ b/frost-secp256k1/tests/snapshots/serialization_tests__check_signature_share_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-secp256k1/tests/serialization_tests.rs +expression: "hex::encode(bytes)" +--- +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9d1c9e899ca306ad27fe1945de0242b81 diff --git a/frost-secp256k1/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap b/frost-secp256k1/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap new file mode 100644 index 00000000..c2211e18 --- /dev/null +++ b/frost-secp256k1/tests/snapshots/serialization_tests__check_signing_commitments_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-secp256k1/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179802c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5f49d8cce diff --git a/frost-secp256k1/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap b/frost-secp256k1/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap new file mode 100644 index 00000000..75efedde --- /dev/null +++ b/frost-secp256k1/tests/snapshots/serialization_tests__check_signing_package_postcard_serialization.snap @@ -0,0 +1,5 @@ +--- +source: frost-secp256k1/tests/serialization_tests.rs +expression: "hex::encode(&bytes)" +--- +01000000000000000000000000000000000000000000000000000000000000002a0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179802c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5f49d8cce0b68656c6c6f20776f726c64f49d8cce diff --git a/gencode/src/main.rs b/gencode/src/main.rs index 483885a7..d30caf13 100644 --- a/gencode/src/main.rs +++ b/gencode/src/main.rs @@ -326,6 +326,7 @@ fn main() -> ExitCode { "tests/recreation_tests.rs", "tests/rerandomized_tests.rs", "tests/serde_tests.rs", + "tests/serialization_tests.rs", "tests/helpers/samples.rs", ] { replaced |= copy_and_replace(