From eff121118a2704b7eaa5a383a594f115960426f2 Mon Sep 17 00:00:00 2001 From: Quang Le Date: Thu, 19 Feb 2026 14:51:07 +0700 Subject: [PATCH 1/4] feat: implement tblsconv --- Cargo.lock | 2 + crates/core/src/types.rs | 6 + crates/crypto/Cargo.toml | 2 + crates/crypto/src/lib.rs | 3 + crates/crypto/src/tblsconv.rs | 247 ++++++++++++++++++++++++++++++++++ 5 files changed, 260 insertions(+) create mode 100644 crates/crypto/src/tblsconv.rs diff --git a/Cargo.lock b/Cargo.lock index 2fdfe94b..470bf5a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5514,6 +5514,8 @@ version = "1.7.1" dependencies = [ "blst", "hex", + "pluto-core", + "pluto-eth2api", "rand 0.8.5", "rand_core 0.6.4", "serde", diff --git a/crates/core/src/types.rs b/crates/core/src/types.rs index 38f407af..9cc95d85 100644 --- a/crates/core/src/types.rs +++ b/crates/core/src/types.rs @@ -441,6 +441,12 @@ impl Signature { } } +impl AsRef<[u8; SIG_LEN]> for Signature { + fn as_ref(&self) -> &[u8; SIG_LEN] { + &self.0 + } +} + /// Signed data type pub trait SignedData: Clone + Serialize + StdDebug { /// The error type diff --git a/crates/crypto/Cargo.toml b/crates/crypto/Cargo.toml index 341f88ca..6919821b 100644 --- a/crates/crypto/Cargo.toml +++ b/crates/crypto/Cargo.toml @@ -9,6 +9,8 @@ publish.workspace = true [dependencies] blst.workspace = true hex.workspace = true +pluto-core.workspace = true +pluto-eth2api.workspace = true rand.workspace = true rand_core.workspace = true serde.workspace = true diff --git a/crates/crypto/src/lib.rs b/crates/crypto/src/lib.rs index dd14f7e2..d5132bfe 100644 --- a/crates/crypto/src/lib.rs +++ b/crates/crypto/src/lib.rs @@ -14,5 +14,8 @@ pub mod blst_impl; /// TBLS trait definition pub mod tbls; +/// Conversions between crypto (tbls), core, and eth2 BLS types. +pub mod tblsconv; + /// Error types and constants pub mod types; diff --git a/crates/crypto/src/tblsconv.rs b/crates/crypto/src/tblsconv.rs new file mode 100644 index 00000000..71b51e71 --- /dev/null +++ b/crates/crypto/src/tblsconv.rs @@ -0,0 +1,247 @@ +//! Conversions between crypto (tbls), core, and eth2 BLS types. +//! +//! This module is a port of the Go `tbls/tblsconv` package, providing +//! conversion functions between the raw BLS byte-array types in +//! [`crate::types`], the core workflow types in [`pluto_core::types`], +//! and the eth2 phase0 types in [`pluto_eth2api::spec::phase0`]. + +use pluto_core::types as core_types; +use pluto_eth2api::spec::phase0; + +use crate::types::{self, PRIVATE_KEY_LENGTH, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH}; + +/// Converts a core workflow [`core_types::Signature`] into a [`types::Signature`]. +pub fn sig_from_core(sig: &core_types::Signature) -> types::Signature { + *sig.as_ref() +} + +/// Converts a [`types::Signature`] into a core workflow [`core_types::Signature`]. +pub fn sig_to_core(sig: types::Signature) -> core_types::Signature { + core_types::Signature::new(sig) +} + +/// Converts a [`types::Signature`] into an eth2 phase0 [`phase0::BLSSignature`]. +pub fn sig_to_eth2(sig: types::Signature) -> phase0::BLSSignature { + sig +} + +/// Converts a [`types::PublicKey`] into an eth2 phase0 [`phase0::BLSPubKey`]. +pub fn pubkey_to_eth2(pk: types::PublicKey) -> phase0::BLSPubKey { + pk +} + +/// Returns a [`types::PrivateKey`] from the given byte slice. +/// +/// Returns an error if the data isn't exactly [`PRIVATE_KEY_LENGTH`] bytes. +pub fn privkey_from_bytes(data: &[u8]) -> Result { + if data.len() != PRIVATE_KEY_LENGTH { + return Err(ConvError::InvalidLength { + expected: PRIVATE_KEY_LENGTH, + got: data.len(), + }); + } + let mut key = [0u8; PRIVATE_KEY_LENGTH]; + key.copy_from_slice(data); + Ok(key) +} + +/// Returns a [`types::PublicKey`] from the given byte slice. +/// +/// Returns an error if the data isn't exactly [`PUBLIC_KEY_LENGTH`] bytes. +pub fn pubkey_from_bytes(data: &[u8]) -> Result { + if data.len() != PUBLIC_KEY_LENGTH { + return Err(ConvError::InvalidLength { + expected: PUBLIC_KEY_LENGTH, + got: data.len(), + }); + } + let mut key = [0u8; PUBLIC_KEY_LENGTH]; + key.copy_from_slice(data); + Ok(key) +} + +/// Returns a [`types::PublicKey`] from a core [`core_types::PubKey`]. +pub fn pubkey_from_core(pk: &core_types::PubKey) -> types::PublicKey { + let bytes: &[u8] = pk.as_ref(); + let mut key = [0u8; PUBLIC_KEY_LENGTH]; + key.copy_from_slice(bytes); + key +} + +/// Returns a [`types::Signature`] from the given byte slice. +/// +/// Returns an error if the data isn't exactly [`SIGNATURE_LENGTH`] bytes. +pub fn signature_from_bytes(data: &[u8]) -> Result { + if data.len() != SIGNATURE_LENGTH { + return Err(ConvError::InvalidLength { + expected: SIGNATURE_LENGTH, + got: data.len(), + }); + } + let mut sig = [0u8; SIGNATURE_LENGTH]; + sig.copy_from_slice(data); + Ok(sig) +} + +/// Conversion error. +#[derive(Debug, thiserror::Error, PartialEq, Eq)] +pub enum ConvError { + /// Data is not of the expected length. + #[error("data is not of the correct length: expected {expected}, got {got}")] + InvalidLength { + /// Expected byte length. + expected: usize, + /// Actual byte length. + got: usize, + }, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_privkey_from_bytes() { + // empty input + assert_eq!( + privkey_from_bytes(&[]), + Err(ConvError::InvalidLength { + expected: PRIVATE_KEY_LENGTH, + got: 0 + }) + ); + + // more data than expected + assert_eq!( + privkey_from_bytes(&vec![42u8; PRIVATE_KEY_LENGTH + 1]), + Err(ConvError::InvalidLength { + expected: PRIVATE_KEY_LENGTH, + got: PRIVATE_KEY_LENGTH + 1 + }) + ); + + // less data than expected + assert_eq!( + privkey_from_bytes(&vec![42u8; PRIVATE_KEY_LENGTH - 1]), + Err(ConvError::InvalidLength { + expected: PRIVATE_KEY_LENGTH, + got: PRIVATE_KEY_LENGTH - 1 + }) + ); + + // correct length + let data = vec![42u8; PRIVATE_KEY_LENGTH]; + let key = privkey_from_bytes(&data).expect("should succeed"); + assert_eq!(key, [42u8; PRIVATE_KEY_LENGTH]); + } + + #[test] + fn test_pubkey_from_bytes() { + // empty input + assert_eq!( + pubkey_from_bytes(&[]), + Err(ConvError::InvalidLength { + expected: PUBLIC_KEY_LENGTH, + got: 0 + }) + ); + + // more data than expected + assert_eq!( + pubkey_from_bytes(&vec![42u8; PUBLIC_KEY_LENGTH + 1]), + Err(ConvError::InvalidLength { + expected: PUBLIC_KEY_LENGTH, + got: PUBLIC_KEY_LENGTH + 1 + }) + ); + + // less data than expected + assert_eq!( + pubkey_from_bytes(&vec![42u8; PUBLIC_KEY_LENGTH - 1]), + Err(ConvError::InvalidLength { + expected: PUBLIC_KEY_LENGTH, + got: PUBLIC_KEY_LENGTH - 1 + }) + ); + + // correct length + let data = vec![42u8; PUBLIC_KEY_LENGTH]; + let key = pubkey_from_bytes(&data).expect("should succeed"); + assert_eq!(key, [42u8; PUBLIC_KEY_LENGTH]); + } + + #[test] + fn test_pubkey_to_eth2() { + let data = vec![42u8; PUBLIC_KEY_LENGTH]; + let pubkey = pubkey_from_bytes(&data).expect("should succeed"); + let res = pubkey_to_eth2(pubkey); + assert_eq!(pubkey[..], res[..]); + } + + #[test] + fn test_pubkey_from_core() { + let bytes = [42u8; PUBLIC_KEY_LENGTH]; + let core_pk = core_types::PubKey::new(bytes); + let res = pubkey_from_core(&core_pk); + assert_eq!(res, bytes); + } + + #[test] + fn test_signature_from_bytes() { + // empty input + assert_eq!( + signature_from_bytes(&[]), + Err(ConvError::InvalidLength { + expected: SIGNATURE_LENGTH, + got: 0 + }) + ); + + // more data than expected + assert_eq!( + signature_from_bytes(&vec![42u8; SIGNATURE_LENGTH + 1]), + Err(ConvError::InvalidLength { + expected: SIGNATURE_LENGTH, + got: SIGNATURE_LENGTH + 1 + }) + ); + + // less data than expected + assert_eq!( + signature_from_bytes(&vec![42u8; SIGNATURE_LENGTH - 1]), + Err(ConvError::InvalidLength { + expected: SIGNATURE_LENGTH, + got: SIGNATURE_LENGTH - 1 + }) + ); + + // correct length + let data = vec![42u8; SIGNATURE_LENGTH]; + let sig = signature_from_bytes(&data).expect("should succeed"); + assert_eq!(sig, [42u8; SIGNATURE_LENGTH]); + } + + #[test] + fn test_sig_from_core() { + let data = [42u8; SIGNATURE_LENGTH]; + let core_sig = core_types::Signature::new(data); + let res = sig_from_core(&core_sig); + assert_eq!(res, data); + } + + #[test] + fn test_sig_to_core() { + let data = [42u8; SIGNATURE_LENGTH]; + let core_sig = sig_to_core(data); + let bytes: &[u8] = core_sig.as_ref(); + assert_eq!(bytes, &data[..]); + } + + #[test] + fn test_sig_to_eth2() { + let data = vec![42u8; SIGNATURE_LENGTH]; + let sig = signature_from_bytes(&data).expect("should succeed"); + let eth2_sig = sig_to_eth2(sig); + assert_eq!(sig[..], eth2_sig[..]); + } +} From 3bc8a29e594eb78f1874b498650bea588a161cc9 Mon Sep 17 00:00:00 2001 From: Quang Le Date: Mon, 23 Feb 2026 17:36:39 +0900 Subject: [PATCH 2/4] fix: clippy --- Cargo.lock | 1 + crates/crypto/Cargo.toml | 3 + crates/crypto/src/tblsconv.rs | 176 +++++++++++----------------------- 3 files changed, 59 insertions(+), 121 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 470bf5a2..9a552ca6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5519,6 +5519,7 @@ dependencies = [ "rand 0.8.5", "rand_core 0.6.4", "serde", + "test-case", "thiserror 2.0.18", ] diff --git a/crates/crypto/Cargo.toml b/crates/crypto/Cargo.toml index 6919821b..04e75b38 100644 --- a/crates/crypto/Cargo.toml +++ b/crates/crypto/Cargo.toml @@ -31,3 +31,6 @@ cast_sign_loss = "deny" needless_return = "deny" panicking_overflow_checks = "deny" unwrap_used = "deny" + +[dev-dependencies] +test-case.workspace = true diff --git a/crates/crypto/src/tblsconv.rs b/crates/crypto/src/tblsconv.rs index 71b51e71..1298073d 100644 --- a/crates/crypto/src/tblsconv.rs +++ b/crates/crypto/src/tblsconv.rs @@ -1,26 +1,24 @@ //! Conversions between crypto (tbls), core, and eth2 BLS types. -//! -//! This module is a port of the Go `tbls/tblsconv` package, providing -//! conversion functions between the raw BLS byte-array types in -//! [`crate::types`], the core workflow types in [`pluto_core::types`], -//! and the eth2 phase0 types in [`pluto_eth2api::spec::phase0`]. use pluto_core::types as core_types; use pluto_eth2api::spec::phase0; use crate::types::{self, PRIVATE_KEY_LENGTH, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH}; -/// Converts a core workflow [`core_types::Signature`] into a [`types::Signature`]. +/// Converts a core workflow [`core_types::Signature`] into a +/// [`types::Signature`]. pub fn sig_from_core(sig: &core_types::Signature) -> types::Signature { *sig.as_ref() } -/// Converts a [`types::Signature`] into a core workflow [`core_types::Signature`]. +/// Converts a [`types::Signature`] into a core workflow +/// [`core_types::Signature`]. pub fn sig_to_core(sig: types::Signature) -> core_types::Signature { core_types::Signature::new(sig) } -/// Converts a [`types::Signature`] into an eth2 phase0 [`phase0::BLSSignature`]. +/// Converts a [`types::Signature`] into an eth2 phase0 +/// [`phase0::BLSSignature`]. pub fn sig_to_eth2(sig: types::Signature) -> phase0::BLSSignature { sig } @@ -34,14 +32,10 @@ pub fn pubkey_to_eth2(pk: types::PublicKey) -> phase0::BLSPubKey { /// /// Returns an error if the data isn't exactly [`PRIVATE_KEY_LENGTH`] bytes. pub fn privkey_from_bytes(data: &[u8]) -> Result { - if data.len() != PRIVATE_KEY_LENGTH { - return Err(ConvError::InvalidLength { - expected: PRIVATE_KEY_LENGTH, - got: data.len(), - }); - } - let mut key = [0u8; PRIVATE_KEY_LENGTH]; - key.copy_from_slice(data); + let key: [u8; PRIVATE_KEY_LENGTH] = data.try_into().map_err(|_| ConvError::InvalidLength { + expected: PRIVATE_KEY_LENGTH, + got: data.len(), + })?; Ok(key) } @@ -49,37 +43,29 @@ pub fn privkey_from_bytes(data: &[u8]) -> Result { /// /// Returns an error if the data isn't exactly [`PUBLIC_KEY_LENGTH`] bytes. pub fn pubkey_from_bytes(data: &[u8]) -> Result { - if data.len() != PUBLIC_KEY_LENGTH { - return Err(ConvError::InvalidLength { - expected: PUBLIC_KEY_LENGTH, - got: data.len(), - }); - } - let mut key = [0u8; PUBLIC_KEY_LENGTH]; - key.copy_from_slice(data); + let key: [u8; PUBLIC_KEY_LENGTH] = data.try_into().map_err(|_| ConvError::InvalidLength { + expected: PUBLIC_KEY_LENGTH, + got: data.len(), + })?; Ok(key) } /// Returns a [`types::PublicKey`] from a core [`core_types::PubKey`]. pub fn pubkey_from_core(pk: &core_types::PubKey) -> types::PublicKey { let bytes: &[u8] = pk.as_ref(); - let mut key = [0u8; PUBLIC_KEY_LENGTH]; - key.copy_from_slice(bytes); - key + bytes + .try_into() + .expect("PubKey must be PUBLIC_KEY_LENGTH bytes") } /// Returns a [`types::Signature`] from the given byte slice. /// /// Returns an error if the data isn't exactly [`SIGNATURE_LENGTH`] bytes. pub fn signature_from_bytes(data: &[u8]) -> Result { - if data.len() != SIGNATURE_LENGTH { - return Err(ConvError::InvalidLength { - expected: SIGNATURE_LENGTH, - got: data.len(), - }); - } - let mut sig = [0u8; SIGNATURE_LENGTH]; - sig.copy_from_slice(data); + let sig: [u8; SIGNATURE_LENGTH] = data.try_into().map_err(|_| ConvError::InvalidLength { + expected: SIGNATURE_LENGTH, + got: data.len(), + })?; Ok(sig) } @@ -98,80 +84,46 @@ pub enum ConvError { #[cfg(test)] mod tests { - use super::*; - - #[test] - fn test_privkey_from_bytes() { - // empty input - assert_eq!( - privkey_from_bytes(&[]), - Err(ConvError::InvalidLength { - expected: PRIVATE_KEY_LENGTH, - got: 0 - }) - ); + use test_case::test_case; - // more data than expected - assert_eq!( - privkey_from_bytes(&vec![42u8; PRIVATE_KEY_LENGTH + 1]), - Err(ConvError::InvalidLength { - expected: PRIVATE_KEY_LENGTH, - got: PRIVATE_KEY_LENGTH + 1 - }) - ); + use super::*; - // less data than expected + #[test_case(&[], PRIVATE_KEY_LENGTH, 0 ; "empty input")] + #[test_case(&[42u8; PRIVATE_KEY_LENGTH + 1], PRIVATE_KEY_LENGTH, PRIVATE_KEY_LENGTH + 1 ; "more data than expected")] + #[test_case(&[42u8; PRIVATE_KEY_LENGTH - 1], PRIVATE_KEY_LENGTH, PRIVATE_KEY_LENGTH - 1 ; "less data than expected")] + fn privkey_from_bytes_invalid(data: &[u8], expected: usize, got: usize) { assert_eq!( - privkey_from_bytes(&vec![42u8; PRIVATE_KEY_LENGTH - 1]), - Err(ConvError::InvalidLength { - expected: PRIVATE_KEY_LENGTH, - got: PRIVATE_KEY_LENGTH - 1 - }) + privkey_from_bytes(data), + Err(ConvError::InvalidLength { expected, got }) ); + } - // correct length + #[test] + fn privkey_from_bytes_valid() { let data = vec![42u8; PRIVATE_KEY_LENGTH]; let key = privkey_from_bytes(&data).expect("should succeed"); assert_eq!(key, [42u8; PRIVATE_KEY_LENGTH]); } - #[test] - fn test_pubkey_from_bytes() { - // empty input + #[test_case(&[], PUBLIC_KEY_LENGTH, 0 ; "empty input")] + #[test_case(&[42u8; PUBLIC_KEY_LENGTH + 1], PUBLIC_KEY_LENGTH, PUBLIC_KEY_LENGTH + 1 ; "more data than expected")] + #[test_case(&[42u8; PUBLIC_KEY_LENGTH - 1], PUBLIC_KEY_LENGTH, PUBLIC_KEY_LENGTH - 1 ; "less data than expected")] + fn pubkey_from_bytes_invalid(data: &[u8], expected: usize, got: usize) { assert_eq!( - pubkey_from_bytes(&[]), - Err(ConvError::InvalidLength { - expected: PUBLIC_KEY_LENGTH, - got: 0 - }) - ); - - // more data than expected - assert_eq!( - pubkey_from_bytes(&vec![42u8; PUBLIC_KEY_LENGTH + 1]), - Err(ConvError::InvalidLength { - expected: PUBLIC_KEY_LENGTH, - got: PUBLIC_KEY_LENGTH + 1 - }) - ); - - // less data than expected - assert_eq!( - pubkey_from_bytes(&vec![42u8; PUBLIC_KEY_LENGTH - 1]), - Err(ConvError::InvalidLength { - expected: PUBLIC_KEY_LENGTH, - got: PUBLIC_KEY_LENGTH - 1 - }) + pubkey_from_bytes(data), + Err(ConvError::InvalidLength { expected, got }) ); + } - // correct length + #[test] + fn pubkey_from_bytes_valid() { let data = vec![42u8; PUBLIC_KEY_LENGTH]; let key = pubkey_from_bytes(&data).expect("should succeed"); assert_eq!(key, [42u8; PUBLIC_KEY_LENGTH]); } #[test] - fn test_pubkey_to_eth2() { + fn pubkey_to_eth2_roundtrip() { let data = vec![42u8; PUBLIC_KEY_LENGTH]; let pubkey = pubkey_from_bytes(&data).expect("should succeed"); let res = pubkey_to_eth2(pubkey); @@ -179,50 +131,32 @@ mod tests { } #[test] - fn test_pubkey_from_core() { + fn pubkey_from_core_roundtrip() { let bytes = [42u8; PUBLIC_KEY_LENGTH]; let core_pk = core_types::PubKey::new(bytes); let res = pubkey_from_core(&core_pk); assert_eq!(res, bytes); } - #[test] - fn test_signature_from_bytes() { - // empty input + #[test_case(&[], SIGNATURE_LENGTH, 0 ; "empty input")] + #[test_case(&[42u8; SIGNATURE_LENGTH + 1], SIGNATURE_LENGTH, SIGNATURE_LENGTH + 1 ; "more data than expected")] + #[test_case(&[42u8; SIGNATURE_LENGTH - 1], SIGNATURE_LENGTH, SIGNATURE_LENGTH - 1 ; "less data than expected")] + fn signature_from_bytes_invalid(data: &[u8], expected: usize, got: usize) { assert_eq!( - signature_from_bytes(&[]), - Err(ConvError::InvalidLength { - expected: SIGNATURE_LENGTH, - got: 0 - }) - ); - - // more data than expected - assert_eq!( - signature_from_bytes(&vec![42u8; SIGNATURE_LENGTH + 1]), - Err(ConvError::InvalidLength { - expected: SIGNATURE_LENGTH, - got: SIGNATURE_LENGTH + 1 - }) - ); - - // less data than expected - assert_eq!( - signature_from_bytes(&vec![42u8; SIGNATURE_LENGTH - 1]), - Err(ConvError::InvalidLength { - expected: SIGNATURE_LENGTH, - got: SIGNATURE_LENGTH - 1 - }) + signature_from_bytes(data), + Err(ConvError::InvalidLength { expected, got }) ); + } - // correct length + #[test] + fn signature_from_bytes_valid() { let data = vec![42u8; SIGNATURE_LENGTH]; let sig = signature_from_bytes(&data).expect("should succeed"); assert_eq!(sig, [42u8; SIGNATURE_LENGTH]); } #[test] - fn test_sig_from_core() { + fn sig_from_core_roundtrip() { let data = [42u8; SIGNATURE_LENGTH]; let core_sig = core_types::Signature::new(data); let res = sig_from_core(&core_sig); @@ -230,7 +164,7 @@ mod tests { } #[test] - fn test_sig_to_core() { + fn sig_to_core_roundtrip() { let data = [42u8; SIGNATURE_LENGTH]; let core_sig = sig_to_core(data); let bytes: &[u8] = core_sig.as_ref(); @@ -238,7 +172,7 @@ mod tests { } #[test] - fn test_sig_to_eth2() { + fn sig_to_eth2_roundtrip() { let data = vec![42u8; SIGNATURE_LENGTH]; let sig = signature_from_bytes(&data).expect("should succeed"); let eth2_sig = sig_to_eth2(sig); From 630a4f8c2e5a50380b2a6bec51b8f68b27f053b1 Mon Sep 17 00:00:00 2001 From: Quang Le Date: Tue, 24 Feb 2026 11:24:38 +0900 Subject: [PATCH 3/4] fix: use assert!(match!()) --- crates/crypto/src/tblsconv.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/crypto/src/tblsconv.rs b/crates/crypto/src/tblsconv.rs index 1298073d..50f12d88 100644 --- a/crates/crypto/src/tblsconv.rs +++ b/crates/crypto/src/tblsconv.rs @@ -70,7 +70,7 @@ pub fn signature_from_bytes(data: &[u8]) -> Result } /// Conversion error. -#[derive(Debug, thiserror::Error, PartialEq, Eq)] +#[derive(Debug, thiserror::Error)] pub enum ConvError { /// Data is not of the expected length. #[error("data is not of the correct length: expected {expected}, got {got}")] @@ -92,10 +92,10 @@ mod tests { #[test_case(&[42u8; PRIVATE_KEY_LENGTH + 1], PRIVATE_KEY_LENGTH, PRIVATE_KEY_LENGTH + 1 ; "more data than expected")] #[test_case(&[42u8; PRIVATE_KEY_LENGTH - 1], PRIVATE_KEY_LENGTH, PRIVATE_KEY_LENGTH - 1 ; "less data than expected")] fn privkey_from_bytes_invalid(data: &[u8], expected: usize, got: usize) { - assert_eq!( + assert!(matches!( privkey_from_bytes(data), - Err(ConvError::InvalidLength { expected, got }) - ); + Err(ConvError::InvalidLength { expected: e, got: g }) if e == expected && g == got + )); } #[test] @@ -109,10 +109,10 @@ mod tests { #[test_case(&[42u8; PUBLIC_KEY_LENGTH + 1], PUBLIC_KEY_LENGTH, PUBLIC_KEY_LENGTH + 1 ; "more data than expected")] #[test_case(&[42u8; PUBLIC_KEY_LENGTH - 1], PUBLIC_KEY_LENGTH, PUBLIC_KEY_LENGTH - 1 ; "less data than expected")] fn pubkey_from_bytes_invalid(data: &[u8], expected: usize, got: usize) { - assert_eq!( + assert!(matches!( pubkey_from_bytes(data), - Err(ConvError::InvalidLength { expected, got }) - ); + Err(ConvError::InvalidLength { expected: e, got: g }) if e == expected && g == got + )); } #[test] @@ -142,10 +142,10 @@ mod tests { #[test_case(&[42u8; SIGNATURE_LENGTH + 1], SIGNATURE_LENGTH, SIGNATURE_LENGTH + 1 ; "more data than expected")] #[test_case(&[42u8; SIGNATURE_LENGTH - 1], SIGNATURE_LENGTH, SIGNATURE_LENGTH - 1 ; "less data than expected")] fn signature_from_bytes_invalid(data: &[u8], expected: usize, got: usize) { - assert_eq!( + assert!(matches!( signature_from_bytes(data), - Err(ConvError::InvalidLength { expected, got }) - ); + Err(ConvError::InvalidLength { expected: e, got: g }) if e == expected && g == got + )); } #[test] From 9357e120a2a452eb0ed7abfa91c45cf4b1c964e7 Mon Sep 17 00:00:00 2001 From: Quang Le Date: Tue, 24 Feb 2026 11:25:37 +0900 Subject: [PATCH 4/4] fix: unwrap instead of expeect --- crates/crypto/src/tblsconv.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/crypto/src/tblsconv.rs b/crates/crypto/src/tblsconv.rs index 50f12d88..16e3ca49 100644 --- a/crates/crypto/src/tblsconv.rs +++ b/crates/crypto/src/tblsconv.rs @@ -101,7 +101,7 @@ mod tests { #[test] fn privkey_from_bytes_valid() { let data = vec![42u8; PRIVATE_KEY_LENGTH]; - let key = privkey_from_bytes(&data).expect("should succeed"); + let key = privkey_from_bytes(&data).unwrap(); assert_eq!(key, [42u8; PRIVATE_KEY_LENGTH]); }