frost_rerandomized_myecoria/
lib.rs1#![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_internal(
115 randomized_verifying_shares,
116 randomized_params.randomized_verifying_key,
117 self.min_signers(),
118 ))
119 }
120}
121
122pub fn sign<C: RandomizedCiphersuite>(
127 signing_package: &frost::SigningPackage<C>,
128 signer_nonces: &frost::round1::SigningNonces<C>,
129 key_package: &frost::keys::KeyPackage<C>,
130 randomizer: Randomizer<C>,
131) -> Result<frost::round2::SignatureShare<C>, Error<C>> {
132 let randomized_params =
133 RandomizedParams::from_randomizer(key_package.verifying_key(), randomizer);
134 let randomized_key_package = key_package.randomize(&randomized_params)?;
135 frost::round2::sign(signing_package, signer_nonces, &randomized_key_package)
136}
137
138pub fn aggregate<C>(
144 signing_package: &frost::SigningPackage<C>,
145 signature_shares: &BTreeMap<frost::Identifier<C>, frost::round2::SignatureShare<C>>,
146 pubkeys: &frost::keys::PublicKeyPackage<C>,
147 randomized_params: &RandomizedParams<C>,
148) -> Result<frost_core::Signature<C>, Error<C>>
149where
150 C: Ciphersuite,
151{
152 let randomized_public_key_package = pubkeys.randomize(randomized_params)?;
153 frost::aggregate(
154 signing_package,
155 signature_shares,
156 &randomized_public_key_package,
157 )
158}
159
160#[derive(Copy, Clone, PartialEq, Eq)]
162#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
163#[cfg_attr(feature = "serde", serde(bound = "C: Ciphersuite"))]
164#[cfg_attr(feature = "serde", serde(transparent))]
165#[cfg_attr(feature = "serde", serde(crate = "self::serde"))]
166pub struct Randomizer<C: Ciphersuite>(SerializableScalar<C>);
167
168impl<C> Randomizer<C>
169where
170 C: Ciphersuite,
171{
172 pub(crate) fn to_scalar(self) -> Scalar<C> {
173 self.0 .0
174 }
175}
176
177impl<C> Randomizer<C>
178where
179 C: RandomizedCiphersuite,
180{
181 #[cfg(feature = "serialization")]
187 pub fn new<R: RngCore + CryptoRng>(
188 mut rng: R,
189 signing_package: &SigningPackage<C>,
190 ) -> Result<Self, Error<C>> {
191 let rng_randomizer = <<C::Group as Group>::Field as Field>::random(&mut rng);
192 Self::from_randomizer_and_signing_package(rng_randomizer, signing_package)
193 }
194
195 #[cfg(feature = "serialization")]
198 fn from_randomizer_and_signing_package(
199 rng_randomizer: <<<C as Ciphersuite>::Group as Group>::Field as Field>::Scalar,
200 signing_package: &SigningPackage<C>,
201 ) -> Result<Randomizer<C>, Error<C>>
202 where
203 C: RandomizedCiphersuite,
204 {
205 let randomizer = C::hash_randomizer(
206 &[
207 <<C::Group as Group>::Field>::serialize(&rng_randomizer).as_ref(),
208 &signing_package.serialize()?,
209 ]
210 .concat(),
211 )
212 .ok_or(Error::SerializationError)?;
213 Ok(Self(SerializableScalar(randomizer)))
214 }
215}
216
217impl<C> Randomizer<C>
218where
219 C: Ciphersuite,
220{
221 pub fn from_scalar(scalar: Scalar<C>) -> Self {
228 Self(SerializableScalar(scalar))
229 }
230
231 pub fn serialize(&self) -> Vec<u8> {
233 self.0.serialize()
234 }
235
236 pub fn deserialize(buf: &[u8]) -> Result<Self, Error<C>> {
239 Ok(Self(SerializableScalar::deserialize(buf)?))
240 }
241}
242
243impl<C> core::fmt::Debug for Randomizer<C>
244where
245 C: Ciphersuite,
246{
247 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
248 f.debug_tuple("Randomizer")
249 .field(&hex::encode(self.0.serialize()))
250 .finish()
251 }
252}
253
254#[derive(Clone, PartialEq, Eq, Getters)]
256pub struct RandomizedParams<C: Ciphersuite> {
257 randomizer: Randomizer<C>,
259 randomizer_element: <C::Group as Group>::Element,
261 randomized_verifying_key: frost_core::VerifyingKey<C>,
263}
264
265impl<C> RandomizedParams<C>
266where
267 C: RandomizedCiphersuite,
268{
269 #[cfg(feature = "serialization")]
272 pub fn new<R: RngCore + CryptoRng>(
273 group_verifying_key: &VerifyingKey<C>,
274 signing_package: &SigningPackage<C>,
275 rng: R,
276 ) -> Result<Self, Error<C>> {
277 Ok(Self::from_randomizer(
278 group_verifying_key,
279 Randomizer::new(rng, signing_package)?,
280 ))
281 }
282}
283
284impl<C> RandomizedParams<C>
285where
286 C: Ciphersuite,
287{
288 pub fn from_randomizer(
294 group_verifying_key: &VerifyingKey<C>,
295 randomizer: Randomizer<C>,
296 ) -> Self {
297 let randomizer_element = <C::Group as Group>::generator() * randomizer.to_scalar();
298 let verifying_key_element = group_verifying_key.to_element();
299 let randomized_verifying_key_element = verifying_key_element + randomizer_element;
300 let randomized_verifying_key = VerifyingKey::<C>::new(randomized_verifying_key_element);
301
302 Self {
303 randomizer,
304 randomizer_element,
305 randomized_verifying_key,
306 }
307 }
308}
309
310impl<C> core::fmt::Debug for RandomizedParams<C>
311where
312 C: Ciphersuite,
313{
314 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
315 f.debug_struct("RandomizedParams")
316 .field("randomizer", &self.randomizer)
317 .field(
318 "randomizer_element",
319 &<C::Group as Group>::serialize(&self.randomizer_element)
320 .map(hex::encode)
321 .unwrap_or("<invalid>".to_string()),
322 )
323 .field("randomized_verifying_key", &self.randomized_verifying_key)
324 .finish()
325 }
326}