mirror of
https://github.com/mii443/RustySecrets.git
synced 2025-08-22 16:25:32 +00:00
Validate shares have the same data length
This commit is contained in:
committed by
Romain Ruetschi
parent
df091b07c1
commit
a6046dde48
@ -64,6 +64,11 @@ error_chain! {
|
|||||||
display("The shares are incompatible with each other because they do not all have the same threshold.")
|
display("The shares are incompatible with each other because they do not all have the same threshold.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IncompatibleDataLengths(sets: Vec<HashSet<u8>>) {
|
||||||
|
description("The shares are incompatible with each other because they do not all have the same share data length.")
|
||||||
|
display("The shares are incompatible with each other because they do not all have the same share data length.")
|
||||||
|
}
|
||||||
|
|
||||||
MissingShares(provided: usize, required: u8) {
|
MissingShares(provided: usize, required: u8) {
|
||||||
description("The number of shares provided is insufficient to recover the secret.")
|
description("The number of shares provided is insufficient to recover the secret.")
|
||||||
display("{} shares are required to recover the secret, found only {}.", required, provided)
|
display("{} shares are required to recover the secret, found only {}.", required, provided)
|
||||||
|
@ -33,14 +33,17 @@ pub(crate) fn validate_shares<S: IsShare>(shares: Vec<S>) -> Result<(u8, Vec<S>)
|
|||||||
let mut result: Vec<S> = Vec::with_capacity(shares_count);
|
let mut result: Vec<S> = Vec::with_capacity(shares_count);
|
||||||
|
|
||||||
let mut k_compatibility_sets = HashMap::new();
|
let mut k_compatibility_sets = HashMap::new();
|
||||||
|
let mut data_len_compatibility_sets = HashMap::new();
|
||||||
|
|
||||||
for share in shares {
|
for share in shares {
|
||||||
let (id, threshold) = (share.get_id(), share.get_threshold());
|
let (id, threshold, data_len) = (share.get_id(), share.get_threshold(), share.get_data().len());
|
||||||
|
|
||||||
if id < 1 {
|
if id < 1 {
|
||||||
bail!(ErrorKind::ShareParsingInvalidShareId(id))
|
bail!(ErrorKind::ShareParsingInvalidShareId(id))
|
||||||
} else if threshold < 2 {
|
} else if threshold < 2 {
|
||||||
bail!(ErrorKind::ShareParsingInvalidShareThreshold(threshold, id))
|
bail!(ErrorKind::ShareParsingInvalidShareThreshold(threshold, id))
|
||||||
|
} else if data_len < 1 {
|
||||||
|
bail!(ErrorKind::ShareParsingErrorEmptyShare(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
k_compatibility_sets
|
k_compatibility_sets
|
||||||
@ -53,9 +56,12 @@ pub(crate) fn validate_shares<S: IsShare>(shares: Vec<S>) -> Result<(u8, Vec<S>)
|
|||||||
bail!(ErrorKind::DuplicateShareId(id));
|
bail!(ErrorKind::DuplicateShareId(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if share.get_data().is_empty() {
|
data_len_compatibility_sets
|
||||||
bail!(ErrorKind::ShareParsingErrorEmptyShare(id))
|
.entry(data_len)
|
||||||
}
|
.or_insert_with(HashSet::new);
|
||||||
|
let data_len_set = data_len_compatibility_sets.get_mut(&data_len).unwrap();
|
||||||
|
data_len_set.insert(id);
|
||||||
|
|
||||||
|
|
||||||
result.push(share);
|
result.push(share);
|
||||||
}
|
}
|
||||||
@ -84,6 +90,23 @@ pub(crate) fn validate_shares<S: IsShare>(shares: Vec<S>) -> Result<(u8, Vec<S>)
|
|||||||
bail!(ErrorKind::MissingShares(shares_count, threshold));
|
bail!(ErrorKind::MissingShares(shares_count, threshold));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate share length consistency
|
||||||
|
let data_len_sets = data_len_compatibility_sets.keys().count();
|
||||||
|
|
||||||
|
match data_len_sets {
|
||||||
|
1 => {} // All shares have the same `data` field len
|
||||||
|
_ => {
|
||||||
|
bail! {
|
||||||
|
ErrorKind::IncompatibleDataLengths(
|
||||||
|
data_len_compatibility_sets
|
||||||
|
.values()
|
||||||
|
.map(|x| x.to_owned())
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok((threshold, result))
|
Ok((threshold, result))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,17 @@ fn test_recover_duplicate_shares_number() {
|
|||||||
recover_secret(&shares, false).unwrap();
|
recover_secret(&shares, false).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic(expected = "IncompatibleDataLengths")]
|
||||||
|
fn test_recover_incompatible_data_lengths() {
|
||||||
|
let share1 = "2-1-CgnlCxRNtnkzENE".to_string();
|
||||||
|
let share2 = "2-2-ChbG46L1zRszs0PPn63XnnupmZTcgYJ3".to_string();
|
||||||
|
|
||||||
|
let shares = vec![share1, share2];
|
||||||
|
|
||||||
|
recover_secret(&shares, false).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "MissingShares")]
|
#[should_panic(expected = "MissingShares")]
|
||||||
fn test_recover_too_few_shares() {
|
fn test_recover_too_few_shares() {
|
||||||
|
Reference in New Issue
Block a user