use std::{ collections::HashMap, io::{self, Read}, }; use rand_core::{RngCore, CryptoRng}; use ciphersuite::Ristretto; use frost::{ dkg::{Participant, ThresholdKeys}, FrostError, algorithm::Algorithm, sign::*, }; use frost_schnorrkel::Schnorrkel; // This wraps a Schnorrkel sign machine into one with a preset message. #[derive(Clone)] pub(crate) struct WrappedSchnorrkelMachine(ThresholdKeys, Vec); impl WrappedSchnorrkelMachine { pub(crate) fn new(keys: ThresholdKeys, msg: Vec) -> Self { Self(keys, msg) } } pub(crate) struct WrappedSchnorrkelSignMachine( as PreprocessMachine>::SignMachine, Vec, ); type Signature = as PreprocessMachine>::Signature; impl PreprocessMachine for WrappedSchnorrkelMachine { type Preprocess = as PreprocessMachine>::Preprocess; type Signature = Signature; type SignMachine = WrappedSchnorrkelSignMachine; fn preprocess( self, rng: &mut R, ) -> (Self::SignMachine, Preprocess>::Addendum>) { let WrappedSchnorrkelMachine(keys, batch) = self; let (machine, preprocess) = AlgorithmMachine::new(Schnorrkel::new(b"substrate"), keys).preprocess(rng); (WrappedSchnorrkelSignMachine(machine, batch), preprocess) } } impl SignMachine for WrappedSchnorrkelSignMachine { type Params = as SignMachine>::Params; type Keys = as SignMachine>::Keys; type Preprocess = as SignMachine>::Preprocess; type SignatureShare = as SignMachine>::SignatureShare; type SignatureMachine = as SignMachine>::SignatureMachine; fn cache(self) -> CachedPreprocess { unimplemented!() } fn from_cache( _algorithm: Schnorrkel, _keys: ThresholdKeys, _cache: CachedPreprocess, ) -> (Self, Self::Preprocess) { unimplemented!() } fn read_preprocess(&self, reader: &mut R) -> io::Result { self.0.read_preprocess(reader) } fn sign( self, preprocesses: HashMap< Participant, Preprocess>::Addendum>, >, msg: &[u8], ) -> Result<(Self::SignatureMachine, SignatureShare), FrostError> { assert!(msg.is_empty()); self.0.sign(preprocesses, &self.1) } }