Skip to content

Commit d474d34

Browse files
committed
Improved error reporting.
1 parent 853de26 commit d474d34

File tree

6 files changed

+60
-72
lines changed

6 files changed

+60
-72
lines changed

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ documentation = "https://docs.rs/sskr"
1313

1414
[dependencies]
1515
bc-rand = "0.1.0"
16-
bc-shamir = "0.2.0"
16+
17+
bc-shamir = { path = "../bc-shamir-rust" }
18+
# bc-shamir = "0.2.0"
19+
20+
thiserror = "1.0.48"
1721

1822
[dev-dependencies]
1923
hex-literal = "0.4.1"

src/encoding.rs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bc_rand::RandomNumberGenerator;
22
use bc_shamir::{split_secret, recover_secret};
3-
use crate::{Error, METADATA_SIZE_BYTES, Secret, Spec, share::SSKRShare};
3+
use crate::{SSKRError, METADATA_SIZE_BYTES, Secret, Spec, share::SSKRShare};
44

55
/// Generates SSKR shares for the given `Spec` and `Secret`.
66
///
@@ -11,7 +11,7 @@ use crate::{Error, METADATA_SIZE_BYTES, Secret, Spec, share::SSKRShare};
1111
pub fn sskr_generate(
1212
spec: &Spec,
1313
master_secret: &Secret
14-
) -> Result<Vec<Vec<Vec<u8>>>, Error> {
14+
) -> Result<Vec<Vec<Vec<u8>>>, SSKRError> {
1515
let mut rng = bc_rand::SecureRandomNumberGenerator;
1616
sskr_generate_using(spec, master_secret, &mut rng)
1717
}
@@ -29,7 +29,7 @@ pub fn sskr_generate_using(
2929
spec: &Spec,
3030
master_secret: &Secret,
3131
random_generator: &mut impl RandomNumberGenerator
32-
) -> Result<Vec<Vec<Vec<u8>>>, Error> {
32+
) -> Result<Vec<Vec<Vec<u8>>>, SSKRError> {
3333
let groups_shares = generate_shares(spec, master_secret, random_generator)?;
3434

3535
let result: Vec<Vec<Vec<u8>>> = groups_shares.iter().map (|group| {
@@ -49,7 +49,7 @@ pub fn sskr_generate_using(
4949
///
5050
/// Returns an error if the shares do not meet the necessary quorum of groups
5151
/// and member shares within each group.
52-
pub fn sskr_combine<T>(shares: &[T]) -> Result<Secret, Error>
52+
pub fn sskr_combine<T>(shares: &[T]) -> Result<Secret, SSKRError>
5353
where
5454
T: AsRef<[u8]>
5555
{
@@ -97,24 +97,24 @@ fn serialize_share(share: &SSKRShare) -> Vec<u8> {
9797
result
9898
}
9999

100-
fn deserialize_share(source: &[u8]) -> Result<SSKRShare, Error> {
100+
fn deserialize_share(source: &[u8]) -> Result<SSKRShare, SSKRError> {
101101
if source.len() < METADATA_SIZE_BYTES {
102-
return Err(Error::ShareLengthInvalid);
102+
return Err(SSKRError::ShareLengthInvalid);
103103
}
104104

105105
let group_threshold = ((source[2] >> 4) + 1) as usize;
106106
let group_count = ((source[2] & 0xf) + 1) as usize;
107107

108108
if group_threshold > group_count {
109-
return Err(Error::GroupThresholdInvalid);
109+
return Err(SSKRError::GroupThresholdInvalid);
110110
}
111111

112112
let identifier = ((source[0] as u16) << 8) | source[1] as u16;
113113
let group_index = (source[3] >> 4) as usize;
114114
let member_threshold = ((source[3] & 0xf) + 1) as usize;
115115
let reserved = source[4] >> 4;
116116
if reserved != 0 {
117-
return Err(Error::ShareReservedBitsInvalid);
117+
return Err(SSKRError::ShareReservedBitsInvalid);
118118
}
119119
let member_index = (source[4] & 0xf) as usize;
120120
let value = Secret::new(&source[METADATA_SIZE_BYTES..])?;
@@ -134,20 +134,20 @@ fn generate_shares(
134134
spec: &Spec,
135135
master_secret: &Secret,
136136
random_generator: &mut impl RandomNumberGenerator
137-
) -> Result<Vec<Vec<SSKRShare>>, Error> {
137+
) -> Result<Vec<Vec<SSKRShare>>, SSKRError> {
138138
// assign a random identifier
139139
let mut identifier = [0u8; 2];
140140
random_generator.fill_random_data(&mut identifier);
141141
let identifier: u16 = ((identifier[0] as u16) << 8) | identifier[1] as u16;
142142

143143
let mut groups_shares: Vec<Vec<SSKRShare>> = Vec::with_capacity(spec.group_count());
144144

145-
let group_secrets = split_secret(spec.group_threshold(), spec.group_count(), master_secret.data(), random_generator).map_err(Error::ShamirError)?;
145+
let group_secrets = split_secret(spec.group_threshold(), spec.group_count(), master_secret.data(), random_generator).map_err(SSKRError::ShamirError)?;
146146

147147
for (group_index, group) in spec.groups().iter().enumerate() {
148148
let group_secret = &group_secrets[group_index];
149149
let member_secrets = split_secret(group.member_threshold(), group.member_count(), group_secret, random_generator)
150-
.map_err(Error::ShamirError)?
150+
.map_err(SSKRError::ShamirError)?
151151
.into_iter().map(Secret::new)
152152
.collect::<Result<Vec<Secret>, _>>()?;
153153
let member_sskr_shares: Vec<SSKRShare> = member_secrets.into_iter().enumerate().map(|(member_index, member_secret)| {
@@ -188,13 +188,13 @@ impl Group {
188188
}
189189
}
190190

191-
fn combine_shares(shares: &[SSKRShare]) -> Result<Secret, Error> {
191+
fn combine_shares(shares: &[SSKRShare]) -> Result<Secret, SSKRError> {
192192
let mut identifier = 0;
193193
let mut group_threshold = 0;
194194
let mut group_count = 0;
195195

196196
if shares.is_empty() {
197-
return Err(Error::SharesEmpty);
197+
return Err(SSKRError::SharesEmpty);
198198
}
199199

200200
let mut next_group = 0;
@@ -215,7 +215,7 @@ fn combine_shares(shares: &[SSKRShare]) -> Result<Secret, Error> {
215215
share.group_count() != group_count ||
216216
share.value().len() != secret_len
217217
{
218-
return Err(Error::ShareSetInvalid);
218+
return Err(SSKRError::ShareSetInvalid);
219219
}
220220
}
221221

@@ -225,11 +225,11 @@ fn combine_shares(shares: &[SSKRShare]) -> Result<Secret, Error> {
225225
if share.group_index() == group.group_index {
226226
group_found = true;
227227
if share.member_threshold() != group.member_threshold {
228-
return Err(Error::MemberThresholdInvalid);
228+
return Err(SSKRError::MemberThresholdInvalid);
229229
}
230230
for k in 0..group.count {
231231
if share.member_index() == group.member_indexes[k] {
232-
return Err(Error::DuplicateMemberIndex);
232+
return Err(SSKRError::DuplicateMemberIndex);
233233
}
234234
}
235235
group.member_indexes.push(share.member_index());
@@ -247,7 +247,7 @@ fn combine_shares(shares: &[SSKRShare]) -> Result<Secret, Error> {
247247
}
248248

249249
if next_group < group_threshold {
250-
return Err(Error::NotEnoughGroups);
250+
return Err(SSKRError::NotEnoughGroups);
251251
}
252252

253253
// here, all of the shares are unpacked into member groups. Now we go through each
@@ -257,12 +257,12 @@ fn combine_shares(shares: &[SSKRShare]) -> Result<Secret, Error> {
257257
let mut master_shares = Vec::with_capacity(16);
258258

259259
for group in groups {
260-
let group_secret = recover_secret(&group.member_indexes, &group.member_shares).map_err(Error::ShamirError)?;
260+
let group_secret = recover_secret(&group.member_indexes, &group.member_shares)?;
261261
master_indexes.push(group.group_index);
262262
master_shares.push(group_secret);
263263
}
264264

265-
let master_secret = recover_secret(&master_indexes, &master_shares).map_err(Error::ShamirError)?;
265+
let master_secret = recover_secret(&master_indexes, &master_shares)?;
266266
let master_secret = Secret::new(master_secret)?;
267267

268268
Ok(master_secret)

src/error.rs

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,53 @@
1+
use thiserror::Error;
2+
13
/// Errors that can occur when using the SSKR library.
2-
#[derive(Debug)]
3-
pub enum Error {
4-
/// When combining shares, the provided shares contained a duplicate member index.
4+
#[derive(Debug, Error)]
5+
pub enum SSKRError {
6+
#[error("When combining shares, the provided shares contained a duplicate member index")]
57
DuplicateMemberIndex,
68

7-
/// When creating a split spec, the group count is invalid.
9+
#[error("When creating a split spec, the group count is invalid")]
810
GroupCountInvalid,
911

10-
/// When creating a split spec, the group threshold is invalid.
12+
#[error("SSKR group threshold is invalid")]
1113
GroupThresholdInvalid,
1214

13-
/// When creating a group spec, the member count is invalid.
15+
#[error("SSKR member count is invalid")]
1416
MemberCountInvalid,
1517

16-
/// When creating a group spec, the member threshold is invalid.
18+
#[error("SSKR member threshold is invalid")]
1719
MemberThresholdInvalid,
1820

19-
/// When combining shares, the provided shares did not contain enough groups.
21+
#[error("SSKR shares did not contain enough groups")]
2022
NotEnoughGroups,
2123

22-
/// When creating a secret, the secret is not of even length.
24+
#[error("SSKR secret is not of even length")]
2325
SecretLengthNotEven,
2426

25-
/// When creating a secret, the secret is too long.
27+
#[error("SSKR secret is too long")]
2628
SecretTooLong,
2729

28-
/// When creating a secret, the secret is too short.
30+
#[error("SSKR secret is too short")]
2931
SecretTooShort,
3032

31-
/// When combining shares, the provided shares did not contain enough serialized bytes.
33+
#[error("SSKR shares did not contain enough serialized bytes")]
3234
ShareLengthInvalid,
3335

34-
/// When combining shares, the provided shares contained invalid reserved bits.
36+
#[error("SSKR shares contained invalid reserved bits")]
3537
ShareReservedBitsInvalid,
3638

37-
/// When combining shares, the provided shares were empty.
39+
#[error("SSKR shares were empty")]
3840
SharesEmpty,
3941

40-
/// When combining shares, the provided shares were invalid.
42+
#[error("SSKR shares were invalid")]
4143
ShareSetInvalid,
4244

43-
/// An error returned from the `bc-shamir` crate.
45+
#[error("SSKR Shamir error: {0}")]
4446
ShamirError(bc_shamir::Error),
4547
}
4648

47-
impl std::fmt::Display for Error {
48-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49-
let s = match *self {
50-
Error::DuplicateMemberIndex => "Duplicate member index".to_string(),
51-
Error::GroupCountInvalid => "Invalid group count".to_string(),
52-
Error::GroupThresholdInvalid => "Invalid group threshold".to_string(),
53-
Error::MemberCountInvalid => "Not enough shares".to_string(),
54-
Error::MemberThresholdInvalid => "Invalid member threshold".to_string(),
55-
Error::NotEnoughGroups => "Not enough groups".to_string(),
56-
Error::SecretLengthNotEven => "Secret is not of even length".to_string(),
57-
Error::SecretTooLong => "Secret is too long".to_string(),
58-
Error::SecretTooShort => "Secret is too short".to_string(),
59-
Error::ShareLengthInvalid => "Not enough serialized bytes".to_string(),
60-
Error::ShareReservedBitsInvalid => "Invalid reserved bits".to_string(),
61-
Error::SharesEmpty => "Empty share set".to_string(),
62-
Error::ShareSetInvalid => "Invalid share set".to_string(),
63-
Error::ShamirError(ref e) => format!("{}", e),
64-
};
65-
f.write_str(&s)
49+
impl From<bc_shamir::Error> for SSKRError {
50+
fn from(err: bc_shamir::Error) -> Self {
51+
SSKRError::ShamirError(err)
6652
}
6753
}
68-
69-
impl std::error::Error for Error {}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ mod spec;
8383
pub use spec::{Spec, GroupSpec};
8484

8585
mod error;
86-
pub use error::Error;
86+
pub use error::SSKRError;
8787

8888
#[cfg(test)]
8989
mod tests {

src/secret.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{Error, MIN_SECRET_LEN, MAX_SECRET_LEN};
1+
use crate::{SSKRError, MIN_SECRET_LEN, MAX_SECRET_LEN};
22

33
/// A secret to be split into shares.
44
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -15,20 +15,20 @@ impl Secret {
1515
///
1616
/// Returns an error if the length of the secret is less than `MIN_SECRET_LEN`, greater than `MAX_SECRET_LEN`,
1717
/// or not even.
18-
pub fn new<T>(data: T) -> Result<Self, Error>
18+
pub fn new<T>(data: T) -> Result<Self, SSKRError>
1919
where
2020
T: AsRef<[u8]>,
2121
{
2222
let data = data.as_ref();
2323
let len = data.len();
2424
if len < MIN_SECRET_LEN {
25-
return Err(Error::SecretTooShort);
25+
return Err(SSKRError::SecretTooShort);
2626
}
2727
if len > MAX_SECRET_LEN {
28-
return Err(Error::SecretTooLong);
28+
return Err(SSKRError::SecretTooLong);
2929
}
3030
if len & 1 != 0 {
31-
return Err(Error::SecretLengthNotEven);
31+
return Err(SSKRError::SecretLengthNotEven);
3232
}
3333
Ok(Self(data.to_vec()))
3434
}

src/spec.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use bc_shamir::MAX_SHARE_COUNT;
22

3-
use crate::Error;
3+
use crate::SSKRError;
44

55
/// A specification for an SSKR split.
66
#[derive(Debug, PartialEq)]
@@ -24,15 +24,15 @@ impl Spec {
2424
/// Returns an error if the group threshold is zero, if the group threshold
2525
/// is greater than the number of groups, or if the number of groups is
2626
/// greater than the maximum share count.
27-
pub fn new(group_threshold: usize, groups: Vec<GroupSpec>) -> Result<Self, Error> {
27+
pub fn new(group_threshold: usize, groups: Vec<GroupSpec>) -> Result<Self, SSKRError> {
2828
if group_threshold == 0 {
29-
return Err(Error::GroupThresholdInvalid);
29+
return Err(SSKRError::GroupThresholdInvalid);
3030
}
3131
if group_threshold > groups.len() {
32-
return Err(Error::GroupThresholdInvalid);
32+
return Err(SSKRError::GroupThresholdInvalid);
3333
}
3434
if groups.len() > MAX_SHARE_COUNT {
35-
return Err(Error::GroupCountInvalid);
35+
return Err(SSKRError::GroupCountInvalid);
3636
}
3737
Ok(Self {
3838
group_threshold,
@@ -83,15 +83,15 @@ impl GroupSpec {
8383
/// Returns an error if the member count is zero, if the member count is
8484
/// greater than the maximum share count, or if the member threshold is
8585
/// greater than the member count.
86-
pub fn new(member_threshold: usize, member_count: usize) -> Result<Self, Error> {
86+
pub fn new(member_threshold: usize, member_count: usize) -> Result<Self, SSKRError> {
8787
if member_count == 0 {
88-
return Err(Error::MemberCountInvalid);
88+
return Err(SSKRError::MemberCountInvalid);
8989
}
9090
if member_count > MAX_SHARE_COUNT {
91-
return Err(Error::MemberCountInvalid);
91+
return Err(SSKRError::MemberCountInvalid);
9292
}
9393
if member_threshold > member_count {
94-
return Err(Error::MemberThresholdInvalid);
94+
return Err(SSKRError::MemberThresholdInvalid);
9595
}
9696
Ok(Self { member_threshold, member_count })
9797
}

0 commit comments

Comments
 (0)