Skip to content

Commit 6f73629

Browse files
committed
Improvements from review
Signed-off-by: maurges <nikita@dfns.co>
1 parent 13358ba commit 6f73629

File tree

5 files changed

+74
-45
lines changed

5 files changed

+74
-45
lines changed

Cargo.lock

-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cggmp21/Cargo.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ digest = { workspace = true }
2626
sha2 = { workspace = true }
2727
rand_core = { workspace = true }
2828
rand_hash = { workspace = true }
29-
rand = { workspace = true, optional = true, features = ["alloc"] }
3029

3130
futures = { workspace = true }
3231

@@ -54,7 +53,7 @@ curve-stark = ["generic-ec/curve-stark", "hd-wallet?/curve-stark"]
5453
hd-wallet = ["dep:hd-wallet", "cggmp21-keygen/hd-wallet"]
5554
hd-slip10 = ["hd-wallet/slip10"]
5655
hd-stark = ["hd-wallet/stark"]
57-
spof = ["key-share/spof", "dep:rand"]
56+
spof = ["key-share/spof"]
5857

5958
state-machine = ["cggmp21-keygen/state-machine"]
6059

cggmp21/src/trusted_dealer.rs

+50-33
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ impl<E: Curve, L: SecurityLevel> TrustedDealerBuilder<E, L> {
147147

148148
/// Generates [`IncompleteKeyShare`]s
149149
///
150+
/// For Shamir secret sharing, it's shared at points `1` to `n`
151+
///
150152
/// Returns error if provided inputs are invalid, or if internal
151153
/// error has occurred.
152154
pub fn generate_core_shares(
@@ -169,11 +171,10 @@ impl<E: Curve, L: SecurityLevel> TrustedDealerBuilder<E, L> {
169171
self,
170172
rng: &mut (impl RngCore + CryptoRng),
171173
) -> Result<Vec<KeyShare<E, L>>, TrustedDealerError> {
172-
let preimages = (1..=self.n)
173-
.map(|i| generic_ec::NonZero::from_scalar(generic_ec::Scalar::from(i)))
174-
.collect::<Option<Vec<_>>>()
175-
.ok_or(Reason::DeriveKeyShareIndex)?;
176-
self.generate_shares_at(preimages, rng)
174+
self.generate_shares_at_internal(
175+
key_share::trusted_dealer::TrustedDealerBuilder::generate_shares,
176+
rng,
177+
)
177178
}
178179

179180
/// Generates [`KeyShare`]s shared at preimages provided. Each share is
@@ -184,16 +185,58 @@ impl<E: Curve, L: SecurityLevel> TrustedDealerBuilder<E, L> {
184185
/// Returns error if provided inputs are invalid, or if internal
185186
/// error has occurred.
186187
pub fn generate_shares_at(
187-
mut self,
188+
self,
188189
preimages: Vec<NonZero<generic_ec::Scalar<E>>>,
189190
rng: &mut (impl RngCore + CryptoRng),
190191
) -> Result<Vec<KeyShare<E, L>>, TrustedDealerError> {
192+
self.generate_shares_at_internal(
193+
|builder, rng| builder.generate_shares_at(preimages, rng),
194+
rng,
195+
)
196+
}
197+
198+
/// Generates [`CoreKeyShare`]s shared at random points
199+
///
200+
/// Returns error if provided inputs are invalid, or if internal
201+
/// error has occurred.
202+
///
203+
/// For Shamir secret sharing, the points at which the value is shared at
204+
/// are chosen at random between `1` and `u16::MAX`. For additive shares,
205+
/// this is the same as [`TrustedDealerBuilder::generate_shares`]
206+
///
207+
/// Returns error if provided inputs are invalid, or if internal
208+
/// error has occurred.
209+
pub fn generate_shares_at_random(
210+
self,
211+
rng: &mut (impl rand_core::RngCore + rand_core::CryptoRng),
212+
) -> Result<Vec<KeyShare<E, L>>, TrustedDealerError> {
213+
self.generate_shares_at_internal(
214+
key_share::trusted_dealer::TrustedDealerBuilder::generate_shares_at_random,
215+
rng,
216+
)
217+
}
218+
219+
fn generate_shares_at_internal<R, F>(
220+
mut self,
221+
inner_generate: F,
222+
rng: &mut R,
223+
) -> Result<Vec<KeyShare<E, L>>, TrustedDealerError>
224+
where
225+
F: FnOnce(
226+
CoreBuilder<E>,
227+
&mut R,
228+
) -> Result<
229+
Vec<IncompleteKeyShare<E>>,
230+
key_share::trusted_dealer::TrustedDealerError,
231+
>,
232+
R: rand_core::RngCore + rand_core::CryptoRng,
233+
{
191234
let n = self.n;
192235
let enable_multiexp = self.enable_mulitexp;
193236
let enable_crt = self.enable_crt;
194237

195238
let primes = self.pregenerated_primes.take();
196-
let core_key_shares = self.inner.generate_shares_at(preimages, rng).map_err(Reason::CoreError)?;
239+
let core_key_shares = inner_generate(self.inner, rng).map_err(Reason::CoreError)?;
197240
let aux_data = if let Some(primes) = primes {
198241
generate_aux_data_with_primes(rng, primes, enable_multiexp, enable_crt)?
199242
} else {
@@ -209,30 +252,6 @@ impl<E: Curve, L: SecurityLevel> TrustedDealerBuilder<E, L> {
209252

210253
Ok(key_shares)
211254
}
212-
213-
/// Generates [`CoreKeyShare`]s shared at random points
214-
///
215-
/// Returns error if provided inputs are invalid, or if internal
216-
/// error has occurred.
217-
///
218-
/// For Shamir secret sharing, the points at which the value is shared at
219-
/// are chosen at random between `1` and `u16::MAX`. For additive shares,
220-
/// this is the same as [`TrustedDealerBuilder::generate_shares`]
221-
///
222-
/// Returns error if provided inputs are invalid, or if internal
223-
/// error has occurred.
224-
pub fn generate_shares_at_random(
225-
self,
226-
rng: &mut (impl rand_core::RngCore + rand_core::CryptoRng),
227-
) -> Result<Vec<KeyShare<E, L>>, TrustedDealerError> {
228-
let key_shares_indexes =
229-
rand::seq::index::sample(rng, usize::from(u16::MAX - 1), usize::from(self.n))
230-
.iter()
231-
.map(|i| generic_ec::NonZero::from_scalar(generic_ec::Scalar::from(i + 1)))
232-
.collect::<Option<Vec<_>>>()
233-
.ok_or(Reason::DeriveKeyShareIndex)?;
234-
self.generate_shares_at(key_shares_indexes, rng)
235-
}
236255
}
237256

238257
/// Generates auxiliary data for `n` signers
@@ -334,8 +353,6 @@ enum Reason {
334353
BuildCrt(#[source] InvalidKeyShare),
335354
#[error("couldn't build multiexp tables")]
336355
BuildMultiexp(#[source] InvalidKeyShare),
337-
#[error("deriving key share index failed")]
338-
DeriveKeyShareIndex,
339356
#[error(transparent)]
340357
CoreError(#[from] key_share::trusted_dealer::TrustedDealerError),
341358
}

key-share/Cargo.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ keywords = ["mpc", "threshold-signatures", "tss"]
1414
generic-ec = { workspace = true, features = ["alloc"] }
1515
generic-ec-zkp = { workspace = true, features = ["alloc"] }
1616
rand_core = { workspace = true, optional = true }
17-
rand = { workspace = true, optional = true, features = ["alloc"] }
1817

1918
hd-wallet = { workspace = true, optional = true }
2019
udigest = { workspace = true, features = ["alloc", "derive"], optional = true }
@@ -34,7 +33,7 @@ default = ["std"]
3433

3534
serde = ["dep:serde", "serde_with", "hex", "generic-ec/serde"]
3635
hd-wallet = ["dep:hd-wallet"]
37-
spof = ["dep:rand_core", "dep:rand"]
36+
spof = ["dep:rand_core"]
3837
udigest = ["dep:udigest", "generic-ec/udigest"]
3938

4039
std = ["dep:thiserror"]

key-share/src/trusted_dealer.rs

+22-7
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,20 @@ impl<E: Curve> TrustedDealerBuilder<E> {
128128
self,
129129
rng: &mut (impl rand_core::RngCore + rand_core::CryptoRng),
130130
) -> Result<Vec<CoreKeyShare<E>>, TrustedDealerError> {
131-
let key_shares_indexes =
132-
rand::seq::index::sample(rng, usize::from(u16::MAX - 1), usize::from(self.n))
133-
.iter()
134-
.map(|i| generic_ec::NonZero::from_scalar(Scalar::from(i + 1)))
135-
.collect::<Option<Vec<_>>>()
136-
.ok_or(Reason::DeriveKeyShareIndex)?;
137-
self.generate_shares_at(key_shares_indexes, rng)
131+
let mut points = Vec::with_capacity(self.n.into());
132+
'each_point: for _ in 0..self.n {
133+
for _ in 0..u16::MAX {
134+
let point = generic_ec::NonZero::<Scalar<E>>::random(rng);
135+
if !points.contains(&point) {
136+
points.push(point);
137+
continue 'each_point;
138+
}
139+
}
140+
// if we did not continue in inner loop, it means we couldn't
141+
// generate a distinct scalar
142+
return Err(Reason::BadRandom.into());
143+
}
144+
self.generate_shares_at(points, rng)
138145
}
139146

140147
/// Generates [`CoreKeyShare`]s shared at preimages provided. Each share is
@@ -149,6 +156,10 @@ impl<E: Curve> TrustedDealerBuilder<E> {
149156
preimages: Vec<NonZero<Scalar<E>>>,
150157
rng: &mut (impl rand_core::RngCore + rand_core::CryptoRng),
151158
) -> Result<Vec<CoreKeyShare<E>>, TrustedDealerError> {
159+
if preimages.len() != usize::from(self.n) {
160+
return Err(Reason::InvalidPreimages.into());
161+
}
162+
152163
let shared_secret_key = self
153164
.shared_secret_key
154165
.unwrap_or_else(|| NonZero::<SecretScalar<_>>::random(rng));
@@ -242,6 +253,10 @@ enum Reason {
242253
DeriveKeyShareIndex,
243254
#[displaydoc("randomly generated share is zero - probability of that is negligible")]
244255
ZeroShare,
256+
#[displaydoc("invalid share preimages given")]
257+
InvalidPreimages,
258+
#[displaydoc("randomness source doesn't have enough entropy")]
259+
BadRandom,
245260
}
246261

247262
impl From<Reason> for TrustedDealerError {

0 commit comments

Comments
 (0)