What changed, and why it matters
This commit only adds and updates unit tests. It does not change any production code. The tests verify that all-zero and all-0xFF seeds are rejected as invalid by several cryptographic modules. There is no security fix or vulnerability introduced here.
No action required. The commit is test-only and does not change runtime behavior. If the underlying production code did not already reject trivial seeds, these new tests would fail, so maintainers should ensure the test suite passes.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit modifies test code in five Rust files to add test cases asserting that trivial seeds (all-zeros or all-0xFF) are rejected by seed-handling functions in Cardano SLIP-23, Ed25519 SLIP-10, RSA, secp256k1, and Zcash modules. One existing test seed value was changed from all-zeros to a non-trivial value to avoid collision with the new invalid-seed test. No production logic was altered.
Changed components
rust/apps/cardano/src/slip23.rs (tests only)rust/keystore/src/algorithms/ed25519/slip10_ed25519.rs (tests only)rust/keystore/src/algorithms/rsa/mod.rs (tests only)rust/keystore/src/algorithms/secp256k1.rs (tests only)rust/keystore/src/algorithms/zcash/mod.rs (tests only)Inspect captured patch +68 / −5
diff --git a/rust/apps/cardano/src/slip23.rs b/rust/apps/cardano/src/slip23.rs
index 73699dd..fb7991d 100644
--- a/rust/apps/cardano/src/slip23.rs
+++ b/rust/apps/cardano/src/slip23.rs
@@ -136,7 +136,7 @@ mod tests {
#[test]
fn test_from_seed_slip23_different_seeds() {
let seed1 = hex::decode("578d685d20b602683dc5171df411d3e2").unwrap();
- let seed2 = hex::decode("00000000000000000000000000000000").unwrap();
+ let seed2 = hex::decode("00000000000000000000000000000001").unwrap();
let result1 = from_seed_slip23(&seed1).unwrap();
let result2 = from_seed_slip23(&seed2).unwrap();
@@ -166,6 +166,15 @@ mod tests {
assert_eq!(components[2], 2147483648); // hardened
}
+ #[test]
+ fn test_from_seed_invalid_seed() {
+ let seed = hex::decode("00000000000000000000000000000000").unwrap();
+ let path = "m/1852'/1815'/0'/0/0";
+ let result = from_seed_slip23_path(&seed, path);
+ assert!(result.is_err());
+ assert!(matches!(result.unwrap_err(), CardanoError::InvalidSeed(_)));
+ }
+
#[test]
fn test_parse_derivation_path_invalid_component() {
let path = "m/1852'/invalid/0'";
diff --git a/rust/keystore/src/algorithms/ed25519/slip10_ed25519.rs b/rust/keystore/src/algorithms/ed25519/slip10_ed25519.rs
index b997f23..8a4988e 100644
--- a/rust/keystore/src/algorithms/ed25519/slip10_ed25519.rs
+++ b/rust/keystore/src/algorithms/ed25519/slip10_ed25519.rs
@@ -508,13 +508,22 @@ mod tests {
assert_eq!(32, key.unwrap().len());
}
- // Test with different seed
+ // all-0xFF seed should be rejected
{
+ let path = "m/0'".to_string();
let seed2 = hex::decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap();
+ let key = get_private_key_by_seed(&seed2, &path);
+ assert!(key.is_err());
+ assert!(matches!(key, Err(KeystoreError::SeedError(_))));
+ }
+
+ // all-zero seed should also be rejected
+ {
let path = "m/0'".to_string();
- let key1 = get_private_key_by_seed(&seed, &path).unwrap();
- let key2 = get_private_key_by_seed(&seed2, &path).unwrap();
- assert_ne!(key1, key2);
+ let zero_seed = vec![0u8; 32];
+ let key = get_private_key_by_seed(&zero_seed, &path);
+ assert!(key.is_err());
+ assert!(matches!(key, Err(KeystoreError::SeedError(_))));
}
}
diff --git a/rust/keystore/src/algorithms/rsa/mod.rs b/rust/keystore/src/algorithms/rsa/mod.rs
index 0c9b2bc..f95b755 100644
--- a/rust/keystore/src/algorithms/rsa/mod.rs
+++ b/rust/keystore/src/algorithms/rsa/mod.rs
@@ -175,6 +175,20 @@ mod tests {
#[test]
fn test_get_rsa_secret_from_seed_invalid_inputs() {
+ // all-zero seed with valid length should be rejected by seed check
+ let zero_seed = vec![0u8; 16];
+ let result = get_rsa_secret_from_seed(zero_seed.as_slice()).unwrap_err();
+ assert!(result
+ .to_string()
+ .contains("invalid seed"));
+
+ // all-0xFF seed with valid length should also be rejected
+ let ff_seed = vec![0xffu8; 32];
+ let result = get_rsa_secret_from_seed(ff_seed.as_slice()).unwrap_err();
+ assert!(result
+ .to_string()
+ .contains("invalid seed"));
+
// Test empty seed
let empty_seed = [];
let result = get_rsa_secret_from_seed(&empty_seed).unwrap_err();
diff --git a/rust/keystore/src/algorithms/secp256k1.rs b/rust/keystore/src/algorithms/secp256k1.rs
index 01980cd..94a6f9d 100644
--- a/rust/keystore/src/algorithms/secp256k1.rs
+++ b/rust/keystore/src/algorithms/secp256k1.rs
@@ -202,6 +202,21 @@ mod tests {
assert_eq!("73c5da0a", master_fingerprint.encode_hex::<String>())
}
+ #[test]
+ fn test_reject_trivial_seed() {
+ // all-zero seed should be rejected
+ let zero_seed = vec![0u8; 32];
+ let result = get_master_fingerprint_by_seed(&zero_seed);
+ assert!(result.is_err());
+ assert!(matches!(result, Err(KeystoreError::SeedError(_))));
+
+ // all-0xFF seed should also be rejected
+ let ff_seed = vec![0xffu8; 32];
+ let result = get_master_fingerprint_by_seed(&ff_seed);
+ assert!(result.is_err());
+ assert!(matches!(result, Err(KeystoreError::SeedError(_))));
+ }
+
#[test]
fn test_derive_extend_public_key() {
let extended_pubkey_str = "xpub6GPqFm1j3L6SppDC1WSMRcUSB4Rt5oPkiHfTsbRTk9o1pzTFN2SrAvbX8a42j48vNrxRbVG8s7RZcNBWBo89yp7iohDAZAuszvnUo7DvJdx";
diff --git a/rust/keystore/src/algorithms/zcash/mod.rs b/rust/keystore/src/algorithms/zcash/mod.rs
index 6673b23..1b2a6b2 100644
--- a/rust/keystore/src/algorithms/zcash/mod.rs
+++ b/rust/keystore/src/algorithms/zcash/mod.rs
@@ -101,6 +101,7 @@ pub fn sign_message_orchard<R: RngCore + CryptoRng>(
#[cfg(test)]
mod tests {
+ use super::*;
use zcash_vendor::{
pasta_curves::Fq,
zcash_keys::keys::{UnifiedAddressRequest, UnifiedSpendingKey},
@@ -159,6 +160,21 @@ mod tests {
);
}
+ #[test]
+ fn test_reject_trivial_seed() {
+ // all-zero seed should be rejected
+ let zero_seed = vec![0u8; 32];
+ let result = calculate_seed_fingerprint(&zero_seed);
+ assert!(result.is_err());
+ assert!(matches!(result, Err(KeystoreError::SeedError(_))));
+
+ // all-0xFF seed should also be rejected
+ let ff_seed = vec![0xffu8; 32];
+ let result = calculate_seed_fingerprint(&ff_seed);
+ assert!(result.is_err());
+ assert!(matches!(result, Err(KeystoreError::SeedError(_))));
+ }
+
#[test]
fn test_orchard_signing() {
let rng_seed = [0u8; 32];
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.