frost_core/
signature.rs

1//! Schnorr signatures over prime order groups (or subgroups)
2
3use alloc::{string::ToString, vec::Vec};
4use derive_getters::Getters;
5
6use crate::{Ciphersuite, Element, Error, Field, Group, Scalar};
7
8/// A Schnorr signature over some prime order group (or subgroup).
9#[derive(Copy, Clone, Eq, PartialEq, Getters)]
10pub struct Signature<C: Ciphersuite> {
11    /// The commitment `R` to the signature nonce.
12    pub(crate) R: Element<C>,
13    /// The response `z` to the challenge computed from the commitment `R`, the verifying key, and
14    /// the message.
15    pub(crate) z: Scalar<C>,
16}
17
18impl<C> Signature<C>
19where
20    C: Ciphersuite,
21    C::Group: Group,
22    <C::Group as Group>::Field: Field,
23{
24    /// Create a new Signature.
25    #[cfg(feature = "internals")]
26    pub fn new(
27        R: <C::Group as Group>::Element,
28        z: <<C::Group as Group>::Field as Field>::Scalar,
29    ) -> Self {
30        Self { R, z }
31    }
32
33    /// Converts default-encoded bytes as
34    /// [`Ciphersuite::SignatureSerialization`] into a `Signature<C>`.
35    #[cfg_attr(feature = "internals", visibility::make(pub))]
36    pub(crate) fn default_deserialize(bytes: &[u8]) -> Result<Self, Error<C>> {
37        // To compute the expected length of the encoded point, encode the generator
38        // and get its length. Note that we can't use the identity because it can be encoded
39        // shorter in some cases (e.g. P-256, which uses SEC1 encoding).
40        let generator = <C::Group>::generator();
41        let mut R_bytes = Vec::from(<C::Group>::serialize(&generator)?.as_ref());
42        let R_bytes_len = R_bytes.len();
43
44        let one = <<C::Group as Group>::Field as Field>::zero();
45        let mut z_bytes =
46            Vec::from(<<C::Group as Group>::Field as Field>::serialize(&one).as_ref());
47        let z_bytes_len = z_bytes.len();
48
49        if bytes.len() != R_bytes_len + z_bytes_len {
50            return Err(Error::MalformedSignature);
51        }
52
53        R_bytes[..].copy_from_slice(bytes.get(0..R_bytes_len).ok_or(Error::MalformedSignature)?);
54
55        let R_serialization = &R_bytes.try_into().map_err(|_| Error::MalformedSignature)?;
56
57        // We extract the exact length of bytes we expect, not just the remaining bytes with `bytes[R_bytes_len..]`
58        z_bytes[..].copy_from_slice(
59            bytes
60                .get(R_bytes_len..R_bytes_len + z_bytes_len)
61                .ok_or(Error::MalformedSignature)?,
62        );
63
64        let z_serialization = &z_bytes.try_into().map_err(|_| Error::MalformedSignature)?;
65
66        Ok(Self {
67            R: <C::Group>::deserialize(R_serialization)?,
68            z: <<C::Group as Group>::Field>::deserialize(z_serialization)?,
69        })
70    }
71
72    /// Converts bytes as [`Ciphersuite::SignatureSerialization`] into a `Signature<C>`.
73    pub fn deserialize(bytes: &[u8]) -> Result<Self, Error<C>> {
74        C::deserialize_signature(bytes)
75    }
76
77    /// Converts this signature to its default byte serialization.
78    #[cfg_attr(feature = "internals", visibility::make(pub))]
79    pub(crate) fn default_serialize(&self) -> Result<Vec<u8>, Error<C>> {
80        let mut bytes = Vec::<u8>::new();
81
82        bytes.extend(<C::Group>::serialize(&self.R)?.as_ref());
83        bytes.extend(<<C::Group as Group>::Field>::serialize(&self.z).as_ref());
84
85        Ok(bytes)
86    }
87
88    /// Converts this signature to its byte serialization.
89    pub fn serialize(&self) -> Result<Vec<u8>, Error<C>> {
90        <C>::serialize_signature(self)
91    }
92}
93
94#[cfg(feature = "serde")]
95impl<C> serde::Serialize for Signature<C>
96where
97    C: Ciphersuite,
98    C::Group: Group,
99    <C::Group as Group>::Field: Field,
100{
101    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
102    where
103        S: serde::Serializer,
104    {
105        serdect::slice::serialize_hex_lower_or_bin(
106            &self.serialize().map_err(serde::ser::Error::custom)?,
107            serializer,
108        )
109    }
110}
111
112#[cfg(feature = "serde")]
113impl<'de, C> serde::Deserialize<'de> for Signature<C>
114where
115    C: Ciphersuite,
116    C::Group: Group,
117    <C::Group as Group>::Field: Field,
118{
119    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
120    where
121        D: serde::Deserializer<'de>,
122    {
123        let bytes = serdect::slice::deserialize_hex_or_bin_vec(deserializer)?;
124        let signature = Signature::deserialize(&bytes)
125            .map_err(|err| serde::de::Error::custom(format!("{err}")))?;
126        Ok(signature)
127    }
128}
129
130impl<C: Ciphersuite> core::fmt::Debug for Signature<C> {
131    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
132        f.debug_struct("Signature")
133            .field(
134                "R",
135                &<C::Group>::serialize(&self.R)
136                    .map(|s| hex::encode(s.as_ref()))
137                    .unwrap_or("<invalid>".to_string()),
138            )
139            .field(
140                "z",
141                &hex::encode(<<C::Group as Group>::Field>::serialize(&self.z).as_ref()),
142            )
143            .finish()
144    }
145}