diff --git a/Cargo.lock b/Cargo.lock index aacfe0b..1cd58cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -218,10 +218,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" [[package]] -name = "const-crc32" -version = "1.3.0" +name = "const-crc32-nostd" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68d13f542d70e5b339bf46f6f74704ac052cfd526c58cd87996bd1ef4615b9a0" +checksum = "808ac43170e95b11dd23d78aa9eaac5bea45776a602955552c4e833f3f0f823d" [[package]] name = "constant_time_eq" @@ -322,13 +322,13 @@ checksum = "f400d0750c0c069e8493f2256cb4da6f604b6d2eeb69a0ca8863acde352f8400" [[package]] name = "derive-getters" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2c35ab6e03642397cdda1dd58abbc05d418aef8e36297f336d5aba060fe8df" +checksum = "0a6433aac097572ea8ccc60b3f2e756c661c9aeed9225cdd4d0cb119cb7ff6ba" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.46", ] [[package]] @@ -391,38 +391,39 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "frost-core" -version = "1.0.0" +version = "2.0.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45d6280625f1603d160df24b23e4984a6a7286f41455ae606823d0104c32e834" +checksum = "ed1383227a6606aacf5df9a17ff57824c6971a0ab225b69b911bec0ba7bbb869" dependencies = [ "byteorder", - "const-crc32", + "const-crc32-nostd", "criterion", "debugless-unwrap", "derive-getters", "document-features", "hex", - "itertools 0.12.0", + "itertools 0.13.0", "postcard", "proptest", "rand_core", "serde", "serde_json", "serdect", - "thiserror", + "thiserror-nostd-notrait", "visibility", "zeroize", ] [[package]] name = "frost-rerandomized" -version = "1.0.0" +version = "2.0.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c58f58ea009000db490efd9a3936d0035647a2b00c7ba8f3868c2ed0306b0b" +checksum = "bdb14a6054f9ce5aa4912c60c11392d42c43acec8295ee1df1f67a9d0b7a73ee" dependencies = [ "derive-getters", "document-features", "frost-core", + "hex", "rand_core", ] @@ -517,9 +518,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -1107,6 +1108,26 @@ dependencies = [ "syn 2.0.46", ] +[[package]] +name = "thiserror-nostd-notrait" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8444e638022c44d2a9337031dee8acb732bcc7fbf52ac654edc236b26408b61" +dependencies = [ + "thiserror-nostd-notrait-impl", +] + +[[package]] +name = "thiserror-nostd-notrait-impl" +version = "1.0.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585e5ef40a784ce60b49c67d762110688d211d395d39e096be204535cf64590e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.46", +] + [[package]] name = "tinytemplate" version = "1.2.1" diff --git a/Cargo.toml b/Cargo.toml index ec4f39a..b81883d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ pasta_curves = { version = "0.5", default-features = false } rand_core = { version = "0.6", default-features = false } serde = { version = "1", optional = true, features = ["derive"] } thiserror = { version = "1.0", optional = true } -frost-rerandomized = { version = "1.0.0", optional = true } +frost-rerandomized = { version = "2.0.0-rc.0", optional = true } [dependencies.zeroize] version = "1" @@ -50,7 +50,7 @@ rand_chacha = "0.3" serde_json = "1.0" num-bigint = "0.4.5" num-traits = "0.2.19" -frost-rerandomized = { version = "1.0.0", features = ["test-impl"] } +frost-rerandomized = { version = "2.0.0-rc.0", features = ["test-impl"] } # `alloc` is only used in test code [dev-dependencies.pasta_curves] diff --git a/src/frost/redjubjub.rs b/src/frost/redjubjub.rs index c025fe6..2a20459 100644 --- a/src/frost/redjubjub.rs +++ b/src/frost/redjubjub.rs @@ -94,8 +94,11 @@ impl Group for JubjubGroup { sapling::SpendAuth::basepoint() } - fn serialize(element: &Self::Element) -> Self::Serialization { - element.to_bytes() + fn serialize(element: &Self::Element) -> Result { + if *element == Self::identity() { + return Err(GroupError::InvalidIdentityElement); + } + Ok(element.to_bytes()) } fn deserialize(buf: &Self::Serialization) -> Result { diff --git a/src/frost/redpallas.rs b/src/frost/redpallas.rs index 5970da2..c788d16 100644 --- a/src/frost/redpallas.rs +++ b/src/frost/redpallas.rs @@ -104,8 +104,11 @@ impl Group for PallasGroup { orchard::SpendAuth::basepoint() } - fn serialize(element: &Self::Element) -> Self::Serialization { - element.to_bytes() + fn serialize(element: &Self::Element) -> Result { + if *element == Self::identity() { + return Err(GroupError::InvalidIdentityElement); + } + Ok(element.to_bytes()) } fn deserialize(buf: &Self::Serialization) -> Result { @@ -331,8 +334,11 @@ pub mod keys { impl EvenY for PublicKeyPackage { fn has_even_y(&self) -> bool { let verifying_key = self.verifying_key(); - let verifying_key_serialized = verifying_key.serialize(); - verifying_key_serialized[31] & 0x80 == 0 + match verifying_key.serialize() { + Ok(verifying_key_serialized) => verifying_key_serialized[31] & 0x80 == 0, + // If serialization fails then it's the identity point, which has even Y + Err(_) => true, + } } fn into_even_y(self, is_even: Option) -> Self { @@ -378,7 +384,10 @@ pub mod keys { .commitment() .coefficients() .iter() - .map(|e| ::Group::serialize(&-e.value())) + .map(|e| { + ::Group::serialize(&-e.value()) + .expect("none of the coefficient commitments are the identity") + }) .collect(); let commitments = VerifiableSecretSharingCommitment::deserialize(coefficients) .expect("Should work since they were just serialized"); @@ -392,8 +401,11 @@ pub mod keys { impl EvenY for KeyPackage { fn has_even_y(&self) -> bool { let pubkey = self.verifying_key(); - let pubkey_serialized = pubkey.serialize(); - pubkey_serialized[31] & 0x80 == 0 + match pubkey.serialize() { + Ok(pubkey_serialized) => pubkey_serialized[31] & 0x80 == 0, + // If serialization fails then it's the identity point, which has even Y + Err(_) => true, + } } fn into_even_y(self, is_even: Option) -> Self { diff --git a/src/hash.rs b/src/hash.rs index cdf4d99..6509a3c 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -28,7 +28,7 @@ impl Default for HStar { .to_state(); Self { state, - _marker: PhantomData::default(), + _marker: PhantomData, } } } @@ -43,7 +43,7 @@ impl HStar { .to_state(); Self { state, - _marker: PhantomData::default(), + _marker: PhantomData, } } diff --git a/tests/frost_redjubjub.rs b/tests/frost_redjubjub.rs index 94d3431..daf1592 100644 --- a/tests/frost_redjubjub.rs +++ b/tests/frost_redjubjub.rs @@ -1,8 +1,10 @@ #![cfg(feature = "frost")] -use frost_rerandomized::frost_core::{Ciphersuite, Group, GroupError}; +use group::GroupEncoding; use rand::thread_rng; +use frost_rerandomized::frost_core::{Ciphersuite, Group, GroupError}; + use reddsa::{frost::redjubjub::JubjubBlake2b512, sapling}; #[test] @@ -26,11 +28,11 @@ fn check_randomized_sign_with_dealer() { // public key (interoperability test) let sig = { - let bytes: [u8; 64] = group_signature.serialize().as_ref().try_into().unwrap(); + let bytes: [u8; 64] = group_signature.serialize().unwrap().try_into().unwrap(); reddsa::Signature::::from(bytes) }; let pk_bytes = { - let bytes: [u8; 32] = group_pubkey.serialize().as_ref().try_into().unwrap(); + let bytes: [u8; 32] = group_pubkey.serialize().unwrap().try_into().unwrap(); reddsa::VerificationKeyBytes::::from(bytes) }; @@ -54,10 +56,12 @@ fn check_sign_with_dkg() { #[test] fn check_deserialize_identity() { - let encoded_identity = ::Group::serialize( + let r = ::Group::serialize( &::Group::identity(), ); - let r = ::Group::deserialize(&encoded_identity); + assert_eq!(r, Err(GroupError::InvalidIdentityElement)); + let raw_identity = ::Group::identity(); + let r = ::Group::deserialize(&raw_identity.to_bytes()); assert_eq!(r, Err(GroupError::InvalidIdentityElement)); } @@ -65,7 +69,8 @@ fn check_deserialize_identity() { fn check_deserialize_non_canonical() { let encoded_generator = ::Group::serialize( &::Group::generator(), - ); + ) + .unwrap(); let r = ::Group::deserialize(&encoded_generator); assert!(r.is_ok()); diff --git a/tests/frost_redpallas.rs b/tests/frost_redpallas.rs index 1843eff..f1f2562 100644 --- a/tests/frost_redpallas.rs +++ b/tests/frost_redpallas.rs @@ -2,9 +2,11 @@ use std::collections::BTreeMap; -use frost_rerandomized::frost_core::{self as frost, Ciphersuite, Group, GroupError}; +use group::GroupEncoding; use rand::thread_rng; +use frost_rerandomized::frost_core::{self as frost, Ciphersuite, Group, GroupError}; + use reddsa::{ frost::redpallas::{keys::EvenY, PallasBlake2b512}, orchard, @@ -28,11 +30,11 @@ fn check_randomized_sign_with_dealer() { // public key (interoperability test) let sig = { - let bytes: [u8; 64] = group_signature.serialize().as_ref().try_into().unwrap(); + let bytes: [u8; 64] = group_signature.serialize().unwrap().try_into().unwrap(); reddsa::Signature::::from(bytes) }; let pk_bytes = { - let bytes: [u8; 32] = group_pubkey.serialize().as_ref().try_into().unwrap(); + let bytes: [u8; 32] = group_pubkey.serialize().unwrap().try_into().unwrap(); reddsa::VerificationKeyBytes::::from(bytes) }; @@ -53,10 +55,12 @@ fn check_sign_with_dkg() { #[test] fn check_deserialize_identity() { - let encoded_identity = ::Group::serialize( + let r = ::Group::serialize( &::Group::identity(), ); - let r = ::Group::deserialize(&encoded_identity); + assert_eq!(r, Err(GroupError::InvalidIdentityElement)); + let raw_identity = ::Group::identity(); + let r = ::Group::deserialize(&raw_identity.to_bytes()); assert_eq!(r, Err(GroupError::InvalidIdentityElement)); } @@ -64,7 +68,8 @@ fn check_deserialize_identity() { fn check_deserialize_non_canonical() { let encoded_generator = ::Group::serialize( &::Group::generator(), - ); + ) + .unwrap(); let r = ::Group::deserialize(&encoded_generator); assert!(r.is_ok());