Skip to content

Commit d0712d8

Browse files
authored
Merge pull request #81 from iron-fish/mat/cleanup
reddsa upgrade + no-std + min round3
2 parents 1a3e331 + a1e2b42 commit d0712d8

16 files changed

+789
-224
lines changed

Cargo.toml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,20 @@ repository = "https://github.com/iron-fish/ironfish-frost"
1212
blake3 = { version = "1.5.0", optional = true }
1313
chacha20 = "0.9.1"
1414
chacha20poly1305 = "0.10.1"
15-
ed25519-dalek = { version = "2.1.0", features = ["rand_core"] }
15+
ed25519-dalek = { version = "2.1.0", default-features = false, features = ["rand_core", "alloc"] }
1616
rand_chacha = { version = "0.3.1", optional = true }
17-
rand_core = "0.6.4"
18-
reddsa = { git = "https://github.com/ZcashFoundation/reddsa.git", rev = "311baf8865f6e21527d1f20750d8f2cf5c9e531a", features = ["frost", "frost-rerandomized"] }
19-
siphasher = { version = "1.0.0", optional = true }
20-
x25519-dalek = { version = "2.0.0", features = ["reusable_secrets", "static_secrets"] }
17+
rand_core = { version = "0.6.4", default-features = false, features = ["alloc"] }
18+
reddsa = { git = "https://github.com/ZcashFoundation/reddsa.git", rev="ed49e9ca0699a6450f6d4a9fe62ff168f5ea1ead", features = ["frost"], default-features = false }
19+
siphasher = { version = "1.0.0", default-features = false }
20+
x25519-dalek = { version = "2.0.0", default-features = false, features = ["reusable_secrets", "static_secrets"] }
2121

2222
[dev-dependencies]
2323
hex-literal = "0.4.1"
2424
rand = "0.8.5"
2525

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

29-
std = []
30-
signing = ["dep:blake3", "dep:rand_chacha", "dep:siphasher", "std"]
31-
dkg = ["std", "signing"]
29+
std = ["reddsa/std"]
30+
signing = ["dep:blake3", "dep:rand_chacha", "std"]
31+
dkg = []

src/checksum.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44

5-
use std::error;
6-
use std::fmt;
5+
use core::fmt;
76

87
use siphasher::sip::SipHasher24;
8+
pub(crate) type ChecksumHasher = SipHasher24;
99

1010
pub(crate) const CHECKSUM_LEN: usize = 8;
1111

1212
pub(crate) type Checksum = u64;
1313

14-
pub(crate) type ChecksumHasher = SipHasher24;
15-
1614
#[derive(Clone, Debug)]
1715
pub enum ChecksumError {
1816
SigningCommitmentError,
@@ -33,4 +31,7 @@ impl fmt::Display for ChecksumError {
3331
}
3432
}
3533

34+
#[cfg(feature = "std")]
35+
use std::error;
36+
#[cfg(feature = "std")]
3637
impl error::Error for ChecksumError {}

src/dkg/error.rs

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/dkg/group_key.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44

5+
use crate::io;
56
use crate::multienc;
67
use crate::participant::Identity;
78
use crate::participant::Secret;
89
use rand_core::CryptoRng;
910
use rand_core::RngCore;
10-
use std::io;
11+
12+
#[cfg(not(feature = "std"))]
13+
extern crate alloc;
14+
#[cfg(not(feature = "std"))]
15+
use alloc::vec::Vec;
1116

1217
pub const GROUP_SECRET_KEY_LEN: usize = 32;
1318

@@ -79,7 +84,7 @@ impl GroupSecretKeyShard {
7984
}
8085

8186
pub fn import(secret: &Secret, exported: &[u8]) -> io::Result<Self> {
82-
let bytes = multienc::decrypt(secret, &exported).map_err(io::Error::other)?;
87+
let bytes = multienc::decrypt(secret, exported).map_err(io::Error::other)?;
8388

8489
if bytes.len() != GROUP_SECRET_KEY_LEN {
8590
return Err(io::Error::other(

src/dkg/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
44

5-
pub mod error;
65
pub mod group_key;
76
pub mod round1;
87
pub mod round2;

src/dkg/round1.rs

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
use crate::checksum::Checksum;
66
use crate::checksum::ChecksumHasher;
77
use crate::checksum::CHECKSUM_LEN;
8-
use crate::dkg::error::Error;
98
use crate::dkg::group_key::GroupSecretKeyShard;
9+
use crate::error::IronfishFrostError;
1010
use crate::frost;
1111
use crate::frost::keys::dkg::round1::Package;
1212
use crate::frost::keys::dkg::round1::SecretPackage;
1313
use crate::frost::keys::VerifiableSecretSharingCommitment;
1414
use crate::frost::Field;
1515
use crate::frost::Identifier;
1616
use crate::frost::JubjubScalarField;
17+
use crate::io;
1718
use crate::multienc;
18-
use crate::multienc::read_encrypted_blob;
1919
use crate::participant;
2020
use crate::participant::Identity;
2121
use crate::serde::read_u16;
@@ -24,12 +24,21 @@ use crate::serde::read_variable_length_bytes;
2424
use crate::serde::write_u16;
2525
use crate::serde::write_variable_length;
2626
use crate::serde::write_variable_length_bytes;
27+
use core::borrow::Borrow;
2728
use rand_core::CryptoRng;
2829
use rand_core::RngCore;
29-
use std::borrow::Borrow;
30-
use std::hash::Hasher;
31-
use std::io;
32-
use std::mem;
30+
31+
use core::hash::Hasher;
32+
use core::mem;
33+
34+
#[cfg(not(feature = "std"))]
35+
extern crate alloc;
36+
37+
#[cfg(not(feature = "std"))]
38+
use alloc::vec::Vec;
39+
40+
#[cfg(not(feature = "std"))]
41+
use alloc::string::ToString;
3342

3443
type Scalar = <JubjubScalarField as Field>::Scalar;
3544

@@ -80,23 +89,24 @@ impl<'a> From<&'a SerializableSecretPackage> for &'a SecretPackage {
8089
}
8190

8291
impl SerializableSecretPackage {
83-
fn serialize_into<W: io::Write>(&self, mut writer: W) -> io::Result<()> {
92+
fn serialize_into<W: io::Write>(&self, mut writer: W) -> Result<(), IronfishFrostError> {
8493
writer.write_all(&self.identifier.serialize())?;
8594
write_variable_length(&mut writer, &self.coefficients, |writer, scalar| {
8695
writer.write_all(&scalar.to_bytes())
8796
})?;
88-
write_variable_length(&mut writer, self.commitment.serialize(), |writer, array| {
97+
let serialized = self.commitment.serialize()?;
98+
write_variable_length(&mut writer, serialized, |writer, array| {
8999
writer.write_all(&array)
90100
})?;
91101
write_u16(&mut writer, self.min_signers)?;
92102
write_u16(&mut writer, self.max_signers)?;
93103
Ok(())
94104
}
95105

96-
fn deserialize_from<R: io::Read>(mut reader: R) -> io::Result<Self> {
106+
fn deserialize_from<R: io::Read>(mut reader: R) -> Result<Self, IronfishFrostError> {
97107
let mut identifier = [0u8; 32];
98108
reader.read_exact(&mut identifier)?;
99-
let identifier = Identifier::deserialize(&identifier).map_err(io::Error::other)?;
109+
let identifier = Identifier::deserialize(&identifier)?;
100110

101111
let coefficients = read_variable_length(&mut reader, |reader| {
102112
let mut scalar = [0u8; 32];
@@ -112,8 +122,7 @@ impl SerializableSecretPackage {
112122
reader.read_exact(&mut array)?;
113123
Ok(array)
114124
},
115-
)?)
116-
.map_err(io::Error::other)?;
125+
)?)?;
117126

118127
let min_signers = read_u16(&mut reader)?;
119128
let max_signers = read_u16(&mut reader)?;
@@ -153,8 +162,9 @@ pub fn export_secret_package<R: RngCore + CryptoRng>(
153162
pub fn import_secret_package(
154163
exported: &[u8],
155164
secret: &participant::Secret,
156-
) -> io::Result<SecretPackage> {
157-
let serialized = multienc::decrypt(secret, &exported).map_err(io::Error::other)?;
165+
) -> Result<SecretPackage, IronfishFrostError> {
166+
let serialized =
167+
multienc::decrypt(secret, exported).map_err(IronfishFrostError::DecryptionError)?;
158168
SerializableSecretPackage::deserialize_from(&serialized[..]).map(|pkg| pkg.into())
159169
}
160170

@@ -247,22 +257,22 @@ impl PublicPackage {
247257
buf
248258
}
249259

250-
pub fn serialize_into<W: io::Write>(&self, mut writer: W) -> io::Result<()> {
260+
pub fn serialize_into<W: io::Write>(&self, mut writer: W) -> Result<(), IronfishFrostError> {
251261
self.identity.serialize_into(&mut writer)?;
252-
let frost_package = self.frost_package.serialize().map_err(io::Error::other)?;
262+
let frost_package = self.frost_package.serialize()?;
253263
write_variable_length_bytes(&mut writer, &frost_package)?;
254-
writer.write_all(&self.group_secret_key_shard_encrypted[..])?;
264+
write_variable_length_bytes(&mut writer, &self.group_secret_key_shard_encrypted)?;
255265
writer.write_all(&self.checksum.to_le_bytes())?;
256266
Ok(())
257267
}
258268

259-
pub fn deserialize_from<R: io::Read>(mut reader: R) -> io::Result<Self> {
269+
pub fn deserialize_from<R: io::Read>(mut reader: R) -> Result<Self, IronfishFrostError> {
260270
let identity = Identity::deserialize_from(&mut reader).expect("reading identity failed");
261271

262272
let frost_package = read_variable_length_bytes(&mut reader)?;
263-
let frost_package = Package::deserialize(&frost_package).map_err(io::Error::other)?;
273+
let frost_package = Package::deserialize(&frost_package)?;
264274

265-
let group_secret_key_shard_encrypted = read_encrypted_blob(&mut reader)?;
275+
let group_secret_key_shard_encrypted = read_variable_length_bytes(&mut reader)?;
266276

267277
let mut checksum = [0u8; CHECKSUM_LEN];
268278
reader.read_exact(&mut checksum)?;
@@ -282,7 +292,7 @@ pub fn round1<'a, I, R>(
282292
min_signers: u16,
283293
participants: I,
284294
mut csrng: R,
285-
) -> Result<(Vec<u8>, PublicPackage), Error>
295+
) -> Result<(Vec<u8>, PublicPackage), IronfishFrostError>
286296
where
287297
I: IntoIterator<Item = &'a Identity>,
288298
R: RngCore + CryptoRng,
@@ -294,25 +304,24 @@ where
294304
let participants = participants;
295305

296306
if !participants.contains(&self_identity) {
297-
return Err(Error::InvalidInput(
307+
return Err(IronfishFrostError::InvalidInput(
298308
"participants must include self_identity".to_string(),
299309
));
300310
}
301311

302312
let max_signers = u16::try_from(participants.len())
303-
.map_err(|_| Error::InvalidInput("too many participants".to_string()))?;
313+
.map_err(|_| IronfishFrostError::InvalidInput("too many participants".to_string()))?;
304314

305315
let (secret_package, public_package) = frost::keys::dkg::part1(
306316
self_identity.to_frost_identifier(),
307317
max_signers,
308318
min_signers,
309319
&mut csrng,
310-
)
311-
.map_err(Error::FrostError)?;
320+
)?;
312321

313322
let encrypted_secret_package =
314323
export_secret_package(&secret_package, self_identity, &mut csrng)
315-
.map_err(Error::EncryptionError)?;
324+
.map_err(IronfishFrostError::EncryptionError)?;
316325

317326
let group_secret_key_shard = GroupSecretKeyShard::random(&mut csrng);
318327

@@ -492,6 +501,13 @@ mod tests {
492501
let deserialized = PublicPackage::deserialize_from(&serialized[..])
493502
.expect("package deserialization failed");
494503

504+
assert_eq!(public_package.identity, deserialized.identity);
505+
assert_eq!(public_package.checksum, deserialized.checksum);
506+
assert_eq!(public_package.frost_package, deserialized.frost_package);
507+
assert_eq!(
508+
public_package.group_secret_key_shard_encrypted,
509+
deserialized.group_secret_key_shard_encrypted
510+
);
495511
assert_eq!(public_package, deserialized);
496512
}
497513

0 commit comments

Comments
 (0)