Skip to content

Commit 1b5a255

Browse files
committed
Migrate to thiserror v2. Error handling improvements.
1 parent d3b15de commit 1b5a255

File tree

6 files changed

+46
-50
lines changed

6 files changed

+46
-50
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ categories = ["cryptography"] # https://cra
1515
bc-rand = "^0.4.0"
1616
bc-shamir = "^0.8.0"
1717

18-
thiserror = "^1.0.48"
18+
thiserror = "^2.0"
1919

2020
[dev-dependencies]
2121
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::{SSKRError, METADATA_SIZE_BYTES, Secret, Spec, share::SSKRShare};
3+
use crate::{Error, Result, 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::{SSKRError, 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>>>, SSKRError> {
14+
) -> Result<Vec<Vec<Vec<u8>>>> {
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>>>, SSKRError> {
32+
) -> Result<Vec<Vec<Vec<u8>>>> {
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, SSKRError>
52+
pub fn sskr_combine<T>(shares: &[T]) -> Result<Secret>
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, SSKRError> {
100+
fn deserialize_share(source: &[u8]) -> Result<SSKRShare> {
101101
if source.len() < METADATA_SIZE_BYTES {
102-
return Err(SSKRError::ShareLengthInvalid);
102+
return Err(Error::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(SSKRError::GroupThresholdInvalid);
109+
return Err(Error::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(SSKRError::ShareReservedBitsInvalid);
117+
return Err(Error::ShareReservedBitsInvalid);
118118
}
119119
let member_index = (source[4] & 0xf) as usize;
120120
let value = Secret::new(&source[METADATA_SIZE_BYTES..])?;
@@ -134,22 +134,22 @@ fn generate_shares(
134134
spec: &Spec,
135135
master_secret: &Secret,
136136
random_generator: &mut impl RandomNumberGenerator
137-
) -> Result<Vec<Vec<SSKRShare>>, SSKRError> {
137+
) -> Result<Vec<Vec<SSKRShare>>> {
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(SSKRError::ShamirError)?;
145+
let group_secrets = split_secret(spec.group_threshold(), spec.group_count(), master_secret.data(), random_generator).map_err(Error::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(SSKRError::ShamirError)?
150+
.map_err(Error::ShamirError)?
151151
.into_iter().map(Secret::new)
152-
.collect::<Result<Vec<Secret>, _>>()?;
152+
.collect::<Result<Vec<Secret>>>()?;
153153
let member_sskr_shares: Vec<SSKRShare> = member_secrets.into_iter().enumerate().map(|(member_index, member_secret)| {
154154
SSKRShare::new(
155155
identifier,
@@ -186,13 +186,13 @@ impl Group {
186186
}
187187
}
188188

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

194194
if shares.is_empty() {
195-
return Err(SSKRError::SharesEmpty);
195+
return Err(Error::SharesEmpty);
196196
}
197197

198198
let mut next_group = 0;
@@ -213,7 +213,7 @@ fn combine_shares(shares: &[SSKRShare]) -> Result<Secret, SSKRError> {
213213
share.group_count() != group_count ||
214214
share.value().len() != secret_len
215215
{
216-
return Err(SSKRError::ShareSetInvalid);
216+
return Err(Error::ShareSetInvalid);
217217
}
218218
}
219219

@@ -223,11 +223,11 @@ fn combine_shares(shares: &[SSKRShare]) -> Result<Secret, SSKRError> {
223223
if share.group_index() == group.group_index {
224224
group_found = true;
225225
if share.member_threshold() != group.member_threshold {
226-
return Err(SSKRError::MemberThresholdInvalid);
226+
return Err(Error::MemberThresholdInvalid);
227227
}
228228
for k in 0..group.member_indexes.len() {
229229
if share.member_index() == group.member_indexes[k] {
230-
return Err(SSKRError::DuplicateMemberIndex);
230+
return Err(Error::DuplicateMemberIndex);
231231
}
232232
}
233233
if group.member_indexes.len() < group.member_threshold {
@@ -248,7 +248,7 @@ fn combine_shares(shares: &[SSKRShare]) -> Result<Secret, SSKRError> {
248248

249249
// Check that we have enough groups to recover the master secret
250250
if next_group < group_threshold {
251-
return Err(SSKRError::NotEnoughGroups);
251+
return Err(Error::NotEnoughGroups);
252252
}
253253

254254
// Here, all of the shares are unpacked into member groups. Now we go through each
@@ -275,7 +275,7 @@ fn combine_shares(shares: &[SSKRShare]) -> Result<Secret, SSKRError> {
275275

276276
// If we don't have enough groups to recover the master secret, return an error
277277
if master_indexes.len() < group_threshold {
278-
return Err(SSKRError::NotEnoughGroups);
278+
return Err(Error::NotEnoughGroups);
279279
}
280280

281281
// Recover the master secret

src/error.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use thiserror::Error;
22

33
/// Errors that can occur when using the SSKR library.
44
#[derive(Debug, Error)]
5-
pub enum SSKRError {
5+
pub enum Error {
66
#[error("When combining shares, the provided shares contained a duplicate member index")]
77
DuplicateMemberIndex,
88

@@ -46,11 +46,7 @@ pub enum SSKRError {
4646
ShareSetInvalid,
4747

4848
#[error("SSKR Shamir error: {0}")]
49-
ShamirError(bc_shamir::Error),
49+
ShamirError(#[from] bc_shamir::Error),
5050
}
5151

52-
impl From<bc_shamir::Error> for SSKRError {
53-
fn from(err: bc_shamir::Error) -> Self {
54-
SSKRError::ShamirError(err)
55-
}
56-
}
52+
pub type Result<T> = std::result::Result<T, Error>;

src/lib.rs

Lines changed: 4 additions & 4 deletions
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::SSKRError;
86+
pub use error::{ Error, Result };
8787

8888
#[cfg(test)]
8989
mod tests {
@@ -108,7 +108,7 @@ mod tests {
108108
unimplemented!()
109109
}
110110

111-
fn try_fill_bytes(&mut self, _dest: &mut [u8]) -> Result<(), rand::Error> {
111+
fn try_fill_bytes(&mut self, _dest: &mut [u8]) -> std::result::Result<(), rand::Error> {
112112
unimplemented!()
113113
}
114114
}
@@ -397,12 +397,12 @@ mod tests {
397397
/// Test fix for [#1](https://github.com/BlockchainCommons/bc-sskr-rust/issues/1).
398398
#[test]
399399
fn example_encode_3() {
400-
use crate::{ SSKRError, Secret, GroupSpec, Spec, sskr_generate, sskr_combine };
400+
use crate::{ Secret, GroupSpec, Spec, sskr_generate, sskr_combine };
401401
use std::str::from_utf8;
402402

403403
const TEXT: &str = "my secret belongs to me.";
404404

405-
fn roundtrip(m: usize, n: usize) -> Result<Secret, SSKRError> {
405+
fn roundtrip(m: usize, n: usize) -> Result<Secret> {
406406
let secret = Secret::new(TEXT).unwrap();
407407
let spec = Spec::new(1, vec![GroupSpec::new(m, n).unwrap()]).unwrap();
408408
let shares: Vec<Vec<Vec<u8>>> = sskr_generate(&spec, &secret).unwrap();

src/secret.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{SSKRError, MIN_SECRET_LEN, MAX_SECRET_LEN};
1+
use crate::{Error, 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, SSKRError>
18+
pub fn new<T>(data: T) -> Result<Self, Error>
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(SSKRError::SecretTooShort);
25+
return Err(Error::SecretTooShort);
2626
}
2727
if len > MAX_SECRET_LEN {
28-
return Err(SSKRError::SecretTooLong);
28+
return Err(Error::SecretTooLong);
2929
}
3030
if len & 1 != 0 {
31-
return Err(SSKRError::SecretLengthNotEven);
31+
return Err(Error::SecretLengthNotEven);
3232
}
3333
Ok(Self(data.to_vec()))
3434
}

src/spec.rs

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

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

55
/// A specification for an SSKR split.
66
#[derive(Debug, Clone, 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, SSKRError> {
27+
pub fn new(group_threshold: usize, groups: Vec<GroupSpec>) -> Result<Self, Error> {
2828
if group_threshold == 0 {
29-
return Err(SSKRError::GroupThresholdInvalid);
29+
return Err(Error::GroupThresholdInvalid);
3030
}
3131
if group_threshold > groups.len() {
32-
return Err(SSKRError::GroupThresholdInvalid);
32+
return Err(Error::GroupThresholdInvalid);
3333
}
3434
if groups.len() > MAX_SHARE_COUNT {
35-
return Err(SSKRError::GroupCountInvalid);
35+
return Err(Error::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, SSKRError> {
86+
pub fn new(member_threshold: usize, member_count: usize) -> Result<Self, Error> {
8787
if member_count == 0 {
88-
return Err(SSKRError::MemberCountInvalid);
88+
return Err(Error::MemberCountInvalid);
8989
}
9090
if member_count > MAX_SHARE_COUNT {
91-
return Err(SSKRError::MemberCountInvalid);
91+
return Err(Error::MemberCountInvalid);
9292
}
9393
if member_threshold > member_count {
94-
return Err(SSKRError::MemberThresholdInvalid);
94+
return Err(Error::MemberThresholdInvalid);
9595
}
9696
Ok(Self { member_threshold, member_count })
9797
}
@@ -107,16 +107,16 @@ impl GroupSpec {
107107
}
108108

109109
/// Parses a group specification from a string.
110-
pub fn parse(s: &str) -> Result<Self, SSKRError> {
110+
pub fn parse(s: &str) -> Result<Self, Error> {
111111
let parts: Vec<&str> = s.split('-').collect();
112112
if parts.len() != 3 {
113-
return Err(SSKRError::GroupSpecInvalid);
113+
return Err(Error::GroupSpecInvalid);
114114
}
115-
let member_threshold = parts[0].parse::<usize>().map_err(|_| SSKRError::GroupSpecInvalid)?;
115+
let member_threshold = parts[0].parse::<usize>().map_err(|_| Error::GroupSpecInvalid)?;
116116
if parts[1] != "of" {
117-
return Err(SSKRError::GroupSpecInvalid);
117+
return Err(Error::GroupSpecInvalid);
118118
}
119-
let member_count = parts[2].parse::<usize>().map_err(|_| SSKRError::GroupSpecInvalid)?;
119+
let member_count = parts[2].parse::<usize>().map_err(|_| Error::GroupSpecInvalid)?;
120120
Self::new(member_threshold, member_count)
121121
}
122122
}

0 commit comments

Comments
 (0)