1#![no_std]
13#![allow(non_snake_case)]
14
15extern crate alloc;
16
17#[cfg(any(test, feature = "test-impl"))]
18pub mod tests;
19
20use alloc::{collections::BTreeMap, string::ToString, vec::Vec};
21
22use derive_getters::Getters;
23pub use frost_core;
24
25#[cfg(feature = "serialization")]
26use frost_core::SigningPackage;
27use frost_core::{
28 self as frost,
29 keys::{KeyPackage, PublicKeyPackage, SigningShare, VerifyingShare},
30 serialization::SerializableScalar,
31 Ciphersuite, Error, Field, Group, Scalar, VerifyingKey,
32};
33
34#[cfg(feature = "serde")]
35use frost_core::serde;
36
37#[cfg(feature = "serialization")]
40use rand_core::{CryptoRng, RngCore};
41
42trait Randomize<C> {
45 fn randomize(&self, params: &RandomizedParams<C>) -> Result<Self, Error<C>>
46 where
47 Self: Sized,
48 C: Ciphersuite;
49}
50
51pub trait RandomizedCiphersuite: Ciphersuite {
53 fn hash_randomizer(m: &[u8]) -> Option<<<Self::Group as Group>::Field as Field>::Scalar>;
55}
56
57impl<C: Ciphersuite> Randomize<C> for KeyPackage<C> {
58 fn randomize(&self, randomized_params: &RandomizedParams<C>) -> Result<Self, Error<C>>
66 where
67 Self: Sized,
68 C: Ciphersuite,
69 {
70 let verifying_share = self.verifying_share();
71 let randomized_verifying_share = VerifyingShare::<C>::new(
72 verifying_share.to_element() + randomized_params.randomizer_element,
73 );
74
75 let signing_share = self.signing_share();
76 let randomized_signing_share =
77 SigningShare::new(signing_share.to_scalar() + randomized_params.randomizer.to_scalar());
78
79 let randomized_key_package = KeyPackage::new(
80 *self.identifier(),
81 randomized_signing_share,
82 randomized_verifying_share,
83 randomized_params.randomized_verifying_key,
84 *self.min_signers(),
85 );
86 Ok(randomized_key_package)
87 }
88}
89
90impl<C: Ciphersuite> Randomize<C> for PublicKeyPackage<C> {
91 fn randomize(&self, randomized_params: &RandomizedParams<C>) -> Result<Self, Error<C>>
97 where
98 Self: Sized,
99 C: Ciphersuite,
100 {
101 let verifying_shares = self.verifying_shares().clone();
102 let randomized_verifying_shares = verifying_shares
103 .iter()
104 .map(|(identifier, verifying_share)| {
105 (
106 *identifier,
107 VerifyingShare::<C>::new(
108 verifying_share.to_element() + randomized_params.randomizer_element,
109 ),
110 )
111 })
112 .collect();
113
114 Ok(PublicKeyPackage::new(
115 randomized_verifying_shares,
116 randomized_params.randomized_verifying_key,
117 ))
118 }
119}
120
121pub fn sign<C: RandomizedCiphersuite>(
126 signing_package: &frost::SigningPackage<C>,
127 signer_nonces: &frost::round1::SigningNonces<C>,
128 key_package: &frost::keys::KeyPackage<C>,
129 randomizer: Randomizer<C>,
130) -> Result<frost::round2::SignatureShare<C>, Error<C>> {
131 let randomized_params =
132 RandomizedParams::from_randomizer(key_package.verifying_key(), randomizer);
133 let randomized_key_package = key_package.randomize(&randomized_params)?;
134 frost::round2::sign(signing_package, signer_nonces, &randomized_key_package)
135}
136
137pub fn aggregate<C>(
143 signing_package: &frost::SigningPackage<C>,
144 signature_shares: &BTreeMap<frost::Identifier<C>, frost::round2::SignatureShare<C>>,
145 pubkeys: &frost::keys::PublicKeyPackage<C>,
146 randomized_params: &RandomizedParams<C>,
147) -> Result<frost_core::Signature<C>, Error<C>>
148where
149 C: Ciphersuite,
150{
151 let randomized_public_key_package = pubkeys.randomize(randomized_params)?;
152 frost::aggregate(
153 signing_package,
154 signature_shares,
155 &randomized_public_key_package,
156 )
157}
158
159#[derive(Copy, Clone, PartialEq, Eq)]
161#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
162#[cfg_attr(feature = "serde", serde(bound = "C: Ciphersuite"))]
163#[cfg_attr(feature = "serde", serde(transparent))]
164#[cfg_attr(feature = "serde", serde(crate = "self::serde"))]
165pub struct Randomizer<C: Ciphersuite>(SerializableScalar<C>);
166
167impl<C> Randomizer<C>
168where
169 C: Ciphersuite,
170{
171 pub(crate) fn to_scalar(self) -> Scalar<C> {
172 self.0 .0
173 }
174}
175
176impl<C> Randomizer<C>
177where
178 C: RandomizedCiphersuite,
179{
180 #[cfg(feature = "serialization")]
186 pub fn new<R: RngCore + CryptoRng>(
187 mut rng: R,
188 signing_package: &SigningPackage<C>,
189 ) -> Result<Self, Error<C>> {
190 let rng_randomizer = <<C::Group as Group>::Field as Field>::random(&mut rng);
191 Self::from_randomizer_and_signing_package(rng_randomizer, signing_package)
192 }
193
194 #[cfg(feature = "serialization")]
197 fn from_randomizer_and_signing_package(
198 rng_randomizer: <<<C as Ciphersuite>::Group as Group>::Field as Field>::Scalar,
199 signing_package: &SigningPackage<C>,
200 ) -> Result<Randomizer<C>, Error<C>>
201 where
202 C: RandomizedCiphersuite,
203 {
204 let randomizer = C::hash_randomizer(
205 &[
206 <<C::Group as Group>::Field>::serialize(&rng_randomizer).as_ref(),
207 &signing_package.serialize()?,
208 ]
209 .concat(),
210 )
211 .ok_or(Error::SerializationError)?;
212 Ok(Self(SerializableScalar(randomizer)))
213 }
214}
215
216impl<C> Randomizer<C>
217where
218 C: Ciphersuite,
219{
220 pub fn from_scalar(scalar: Scalar<C>) -> Self {
227 Self(SerializableScalar(scalar))
228 }
229
230 pub fn serialize(&self) -> Vec<u8> {
232 self.0.serialize()
233 }
234
235 pub fn deserialize(buf: &[u8]) -> Result<Self, Error<C>> {
238 Ok(Self(SerializableScalar::deserialize(buf)?))
239 }
240}
241
242impl<C> core::fmt::Debug for Randomizer<C>
243where
244 C: Ciphersuite,
245{
246 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
247 f.debug_tuple("Randomizer")
248 .field(&hex::encode(self.0.serialize()))
249 .finish()
250 }
251}
252
253#[derive(Clone, PartialEq, Eq, Getters)]
255pub struct RandomizedParams<C: Ciphersuite> {
256 randomizer: Randomizer<C>,
258 randomizer_element: <C::Group as Group>::Element,
260 randomized_verifying_key: frost_core::VerifyingKey<C>,
262}
263
264impl<C> RandomizedParams<C>
265where
266 C: RandomizedCiphersuite,
267{
268 #[cfg(feature = "serialization")]
271 pub fn new<R: RngCore + CryptoRng>(
272 group_verifying_key: &VerifyingKey<C>,
273 signing_package: &SigningPackage<C>,
274 rng: R,
275 ) -> Result<Self, Error<C>> {
276 Ok(Self::from_randomizer(
277 group_verifying_key,
278 Randomizer::new(rng, signing_package)?,
279 ))
280 }
281}
282
283impl<C> RandomizedParams<C>
284where
285 C: Ciphersuite,
286{
287 pub fn from_randomizer(
293 group_verifying_key: &VerifyingKey<C>,
294 randomizer: Randomizer<C>,
295 ) -> Self {
296 let randomizer_element = <C::Group as Group>::generator() * randomizer.to_scalar();
297 let verifying_key_element = group_verifying_key.to_element();
298 let randomized_verifying_key_element = verifying_key_element + randomizer_element;
299 let randomized_verifying_key = VerifyingKey::<C>::new(randomized_verifying_key_element);
300
301 Self {
302 randomizer,
303 randomizer_element,
304 randomized_verifying_key,
305 }
306 }
307}
308
309impl<C> core::fmt::Debug for RandomizedParams<C>
310where
311 C: Ciphersuite,
312{
313 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
314 f.debug_struct("RandomizedParams")
315 .field("randomizer", &self.randomizer)
316 .field(
317 "randomizer_element",
318 &<C::Group as Group>::serialize(&self.randomizer_element)
319 .map(hex::encode)
320 .unwrap_or("<invalid>".to_string()),
321 )
322 .field("randomized_verifying_key", &self.randomized_verifying_key)
323 .finish()
324 }
325}