Skip to content

Commit 4da5c4d

Browse files
author
Hugh Cunningham
committed
restores previous error types and formatting
brings back DecryptionError and EncryptionError type enums adds string parameter back to InvalidInput, restores prior error message, and adds error messages when std and string formatting not available
1 parent 0a0b841 commit 4da5c4d

File tree

5 files changed

+126
-28
lines changed

5 files changed

+126
-28
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ hex-literal = "0.4.1"
2424
rand = "0.8.5"
2525

2626
[features]
27-
default = ["signing"]
27+
default = ["dkg", "std"]
2828

2929
std = ["reddsa/std"]
3030
signing = ["dep:blake3", "dep:rand_chacha", "std"]

src/dkg/round1.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ extern crate alloc;
3737
#[cfg(not(feature = "std"))]
3838
use alloc::vec::Vec;
3939

40+
#[cfg(not(feature = "std"))]
41+
use alloc::string::ToString;
42+
4043
type Scalar = <JubjubScalarField as Field>::Scalar;
4144

4245
/// Copy of the [`frost_core::dkg::round1::SecretPackage`] struct. Necessary to implement
@@ -160,7 +163,8 @@ pub fn import_secret_package(
160163
exported: &[u8],
161164
secret: &participant::Secret,
162165
) -> Result<SecretPackage, IronfishFrostError> {
163-
let serialized = multienc::decrypt(secret, exported).map_err(io::Error::other)?;
166+
let serialized =
167+
multienc::decrypt(secret, exported).map_err(IronfishFrostError::DecryptionError)?;
164168
SerializableSecretPackage::deserialize_from(&serialized[..]).map(|pkg| pkg.into())
165169
}
166170

@@ -300,11 +304,13 @@ where
300304
let participants = participants;
301305

302306
if !participants.contains(&self_identity) {
303-
return Err(IronfishFrostError::InvalidInput);
307+
return Err(IronfishFrostError::InvalidInput(
308+
"participants must include self_identity".to_string(),
309+
));
304310
}
305311

306-
let max_signers =
307-
u16::try_from(participants.len()).map_err(|_| IronfishFrostError::InvalidInput)?;
312+
let max_signers = u16::try_from(participants.len())
313+
.map_err(|_| IronfishFrostError::InvalidInput("too many participants".to_string()))?;
308314

309315
let (secret_package, public_package) = frost::keys::dkg::part1(
310316
self_identity.to_frost_identifier(),
@@ -314,7 +320,8 @@ where
314320
)?;
315321

316322
let encrypted_secret_package =
317-
export_secret_package(&secret_package, self_identity, &mut csrng)?;
323+
export_secret_package(&secret_package, self_identity, &mut csrng)
324+
.map_err(IronfishFrostError::EncryptionError)?;
318325

319326
let group_secret_key_shard = GroupSecretKeyShard::random(&mut csrng);
320327

src/dkg/round2.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ extern crate alloc;
4141
#[cfg(not(feature = "std"))]
4242
use alloc::collections::BTreeMap;
4343
#[cfg(not(feature = "std"))]
44+
use alloc::string::ToString;
45+
#[cfg(not(feature = "std"))]
4446
use alloc::vec::Vec;
4547

4648
type Scalar = <JubjubScalarField as Field>::Scalar;
@@ -163,7 +165,8 @@ pub fn import_secret_package(
163165
exported: &[u8],
164166
secret: &participant::Secret,
165167
) -> Result<SecretPackage, IronfishFrostError> {
166-
let serialized = multienc::decrypt(secret, exported).map_err(io::Error::other)?;
168+
let serialized =
169+
multienc::decrypt(secret, &exported).map_err(IronfishFrostError::DecryptionError)?;
167170
SerializableSecretPackage::deserialize_from(&serialized[..]).map(|pkg| pkg.into())
168171
}
169172

@@ -377,7 +380,17 @@ where
377380

378381
// Ensure that the number of public packages provided matches max_signers
379382
if round1_public_packages.len() != max_signers as usize {
380-
return Err(IronfishFrostError::InvalidInput);
383+
#[cfg(feature = "std")]
384+
return Err(IronfishFrostError::InvalidInput(format!(
385+
"expected {} public packages, got {}",
386+
max_signers,
387+
round1_public_packages.len()
388+
)));
389+
390+
#[cfg(not(feature = "std"))]
391+
return Err(IronfishFrostError::InvalidInput(
392+
"incorrect number of round 1 public packages".to_string(),
393+
));
381394
}
382395

383396
let expected_round1_checksum = round1::input_checksum(
@@ -402,7 +415,16 @@ where
402415
.insert(frost_identifier, frost_package)
403416
.is_some()
404417
{
405-
return Err(IronfishFrostError::InvalidInput);
418+
#[cfg(feature = "std")]
419+
return Err(IronfishFrostError::InvalidInput(format!(
420+
"multiple public packages provided for identity {}",
421+
public_package.identity()
422+
)));
423+
424+
#[cfg(not(feature = "std"))]
425+
return Err(IronfishFrostError::InvalidInput(
426+
"multiple public packages provided for an identity".to_string(),
427+
));
406428
}
407429

408430
identities.insert(frost_identifier, identity);
@@ -428,7 +450,8 @@ where
428450

429451
// Encrypt the secret package
430452
let encrypted_secret_package =
431-
export_secret_package(&round2_secret_package, &self_identity, &mut csrng)?;
453+
export_secret_package(&round2_secret_package, &self_identity, &mut csrng)
454+
.map_err(IronfishFrostError::EncryptionError)?;
432455

433456
// Convert the Identifier->Package map to an Identity->PublicPackage map
434457
let mut round2_public_packages = Vec::new();
@@ -690,7 +713,7 @@ mod tests {
690713
);
691714

692715
match result {
693-
Err(IronfishFrostError::InvalidInput) => (),
716+
Err(IronfishFrostError::InvalidInput(_)) => (),
694717
_ => panic!("dkg round2 should have failed with InvalidInput"),
695718
}
696719
}
@@ -718,7 +741,7 @@ mod tests {
718741

719742
// We can use `assert_matches` once it's stabilized
720743
match result {
721-
Err(IronfishFrostError::InvalidInput) => (),
744+
Err(IronfishFrostError::InvalidInput(_)) => (),
722745
_ => panic!("dkg round2 should have failed with InvalidInput"),
723746
}
724747
}

src/dkg/round3.rs

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ extern crate alloc;
3232
#[cfg(not(feature = "std"))]
3333
use alloc::collections::BTreeMap;
3434
#[cfg(not(feature = "std"))]
35+
use alloc::string::ToString;
36+
#[cfg(not(feature = "std"))]
3537
use alloc::vec::Vec;
3638

3739
#[derive(Clone, Eq, PartialEq, Debug)]
@@ -134,12 +136,32 @@ where
134136
// Ensure that the number of public packages provided matches max_signers
135137
let expected_round1_packages = max_signers as usize;
136138
if round1_public_packages.len() != expected_round1_packages {
137-
return Err(IronfishFrostError::InvalidInput);
139+
#[cfg(feature = "std")]
140+
return Err(IronfishFrostError::InvalidInput(format!(
141+
"expected {} round 1 public packages, got {}",
142+
expected_round1_packages,
143+
round1_public_packages.len()
144+
)));
145+
146+
#[cfg(not(feature = "std"))]
147+
return Err(IronfishFrostError::InvalidInput(
148+
"incorrect number of round 1 public packages",
149+
));
138150
}
139151

140152
let expected_round2_packages = expected_round1_packages.saturating_sub(1);
141153
if round2_public_packages.len() != expected_round2_packages {
142-
return Err(IronfishFrostError::InvalidInput);
154+
#[cfg(feature = "std")]
155+
return Err(IronfishFrostError::InvalidInput(format!(
156+
"expected {} round 2 public packages, got {}",
157+
expected_round2_packages,
158+
round2_public_packages.len()
159+
)));
160+
161+
#[cfg(not(feature = "std"))]
162+
return Err(IronfishFrostError::InvalidInput(
163+
"incorrect number of round 2 public packages",
164+
));
143165
}
144166

145167
let expected_round1_checksum = round1::input_checksum(
@@ -166,10 +188,21 @@ where
166188
.insert(frost_identifier, frost_package)
167189
.is_some()
168190
{
169-
return Err(IronfishFrostError::InvalidInput);
191+
#[cfg(feature = "std")]
192+
return Err(IronfishFrostError::InvalidInput(format!(
193+
"multiple round 1 public packages provided for identity {}",
194+
public_package.identity()
195+
)));
196+
197+
#[cfg(not(feature = "std"))]
198+
return Err(IronfishFrostError::InvalidInput(
199+
"multiple round 1 public packages provided for an identity",
200+
));
170201
}
171202

172-
let gsk_shard = public_package.group_secret_key_shard(secret)?;
203+
let gsk_shard = public_package
204+
.group_secret_key_shard(secret)
205+
.map_err(IronfishFrostError::DecryptionError)?;
173206
gsk_shards.push(gsk_shard);
174207
identities.push(identity.clone());
175208
}
@@ -181,7 +214,9 @@ where
181214
// inputs
182215
round1_frost_packages
183216
.remove(&identity.to_frost_identifier())
184-
.ok_or(IronfishFrostError::InvalidInput)?;
217+
.ok_or(IronfishFrostError::InvalidInput(
218+
"missing round 1 public package for own identity".to_string(),
219+
))?;
185220

186221
let expected_round2_checksum =
187222
round2::input_checksum(round1_public_packages.iter().map(Borrow::borrow));
@@ -195,7 +230,16 @@ where
195230
}
196231

197232
if !identity.eq(public_package.recipient_identity()) {
198-
return Err(IronfishFrostError::InvalidInput);
233+
#[cfg(feature = "std")]
234+
return Err(IronfishFrostError::InvalidInput(format!(
235+
"round 2 public package does not have the correct recipient identity {:?}",
236+
public_package.recipient_identity().serialize()
237+
)));
238+
239+
#[cfg(not(feature = "std"))]
240+
return Err(IronfishFrostError::InvalidInput(
241+
"round 2 public package does not have the correct recipient identity",
242+
));
199243
}
200244

201245
let frost_identifier = public_package.sender_identity().to_frost_identifier();
@@ -205,7 +249,16 @@ where
205249
.insert(frost_identifier, frost_package)
206250
.is_some()
207251
{
208-
return Err(IronfishFrostError::InvalidInput);
252+
#[cfg(feature = "std")]
253+
return Err(IronfishFrostError::InvalidInput(format!(
254+
"multiple round 2 public packages provided for identity {}",
255+
public_package.sender_identity(),
256+
)));
257+
258+
#[cfg(not(feature = "std"))]
259+
return Err(IronfishFrostError::InvalidInput(
260+
"multiple round 2 public packages provided for an identity".to_string(),
261+
));
209262
}
210263
}
211264

@@ -334,7 +387,7 @@ mod tests {
334387
);
335388

336389
match result {
337-
Err(IronfishFrostError::InvalidInput) => (),
390+
Err(IronfishFrostError::InvalidInput(_)) => (),
338391
_ => panic!("dkg round3 should have failed with InvalidInput"),
339392
}
340393
}

src/error.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,18 @@ use crate::io;
99

1010
use crate::checksum::ChecksumError;
1111

12+
#[cfg(not(feature = "std"))]
13+
extern crate alloc;
14+
#[cfg(not(feature = "std"))]
15+
use alloc::string::String;
16+
1217
#[derive(Debug)]
1318
pub enum IronfishFrostError {
14-
InvalidInput,
19+
InvalidInput(String),
1520
StdError,
1621
IoError(io::Error),
22+
DecryptionError(io::Error),
23+
EncryptionError(io::Error),
1724
FrostError(FrostError<JubjubBlake2b512>),
1825
SignatureError(ed25519_dalek::SignatureError),
1926
ChecksumError(ChecksumError),
@@ -44,22 +51,30 @@ use std::fmt;
4451
impl fmt::Display for IronfishFrostError {
4552
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
4653
match self {
47-
Self::InvalidInput => {
48-
write!(f, "invalid input")?;
49-
Ok(())
54+
Self::InvalidInput(e) => {
55+
write!(f, "invalid input: ")?;
56+
e.fmt(f)
5057
}
5158
Self::StdError => {
5259
write!(f, "std error")?;
5360
Ok(())
5461
}
55-
Self::FrostError(e) => {
56-
write!(f, "frost error: ")?;
57-
e.fmt(f)
58-
}
5962
Self::IoError(e) => {
6063
write!(f, "io error: ")?;
6164
e.fmt(f)
6265
}
66+
Self::DecryptionError(e) => {
67+
write!(f, "decryption error: ")?;
68+
e.fmt(f)
69+
}
70+
Self::EncryptionError(e) => {
71+
write!(f, "encryption error: ")?;
72+
e.fmt(f)
73+
}
74+
Self::FrostError(e) => {
75+
write!(f, "frost error: ")?;
76+
e.fmt(f)
77+
}
6378
Self::SignatureError(e) => {
6479
write!(f, "signature rror: ")?;
6580
e.fmt(f)

0 commit comments

Comments
 (0)