//! Schnorr signature signing keys use rand_core::{CryptoRng, RngCore}; use crate::{random_nonzero, Ciphersuite, Error, Field, Group, Scalar, Signature, VerifyingKey}; /// A signing key for a Schnorr signature on a FROST [`Ciphersuite::Group`]. #[derive(Copy, Clone, PartialEq, Eq)] pub struct SigningKey where C: Ciphersuite, { pub(crate) scalar: Scalar, } impl SigningKey where C: Ciphersuite, { /// Generate a new signing key. pub fn new(rng: &mut R) -> SigningKey { let scalar = random_nonzero::(rng); SigningKey { scalar } } /// Deserialize from bytes pub fn deserialize( bytes: <::Field as Field>::Serialization, ) -> Result, Error> { <::Field as Field>::deserialize(&bytes) .map(|scalar| SigningKey { scalar }) .map_err(|e| e.into()) } /// Serialize `SigningKey` to bytes pub fn serialize(&self) -> <::Field as Field>::Serialization { <::Field as Field>::serialize(&self.scalar) } /// Create a signature `msg` using this `SigningKey`. pub fn sign(&self, mut rng: R, msg: &[u8]) -> Signature { let k = random_nonzero::(&mut rng); let R = ::generator() * k; // Generate Schnorr challenge let c = crate::challenge::(&R, &VerifyingKey::::from(*self).element, msg); let z = k + (c.0 * self.scalar); Signature { R, z } } } impl std::fmt::Debug for SigningKey where C: Ciphersuite, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("SigningKey").field(&"").finish() } } impl From<&SigningKey> for VerifyingKey where C: Ciphersuite, { fn from(signing_key: &SigningKey) -> Self { VerifyingKey { element: C::Group::generator() * signing_key.scalar, } } } impl From> for VerifyingKey where C: Ciphersuite, { fn from(signing_key: SigningKey) -> Self { VerifyingKey::::from(&signing_key) } }