Skip to main content

k256/schnorr/
verifying.rs

1//! Taproot Schnorr verifying key.
2
3use super::{CHALLENGE_TAG, Signature, tagged_hash};
4use crate::{AffinePoint, FieldBytes, ProjectivePoint, PublicKey, Scalar};
5use elliptic_curve::{
6    group::CurveAffine,
7    ops::{MulByGeneratorVartime, Reduce},
8    point::DecompactPoint,
9};
10use sha2::{
11    Digest, Sha256,
12    digest::{Update, consts::U32},
13};
14use signature::{
15    DigestVerifier, Error, MultipartVerifier, Result, Verifier, hazmat::PrehashVerifier,
16};
17
18#[cfg(feature = "serde")]
19use serdect::serde::{Deserialize, Serialize, de, ser};
20
21/// Taproot Schnorr verifying key.
22#[derive(Copy, Clone, Debug, Eq, PartialEq)]
23pub struct VerifyingKey {
24    /// Inner public key
25    pub(super) inner: PublicKey,
26}
27
28impl VerifyingKey {
29    /// Parse verifying key from big endian-encoded x-coordinate.
30    ///
31    /// # Errors
32    /// Returns an error if a curve point could not be reconstructed from `x_bytes.`
33    pub fn from_bytes(x_bytes: &FieldBytes) -> Result<Self> {
34        AffinePoint::decompact(x_bytes)
35            .into_option()
36            .ok_or_else(Error::new)?
37            .try_into()
38    }
39
40    /// Parse verifying key from big endian-encoded x-coordinate.
41    ///
42    /// # Errors
43    /// Returns an error if `x_bytes` is not 32-bytes long or if a valid curve point could not
44    /// be reconstructed.
45    pub fn from_slice(x_bytes: &[u8]) -> Result<Self> {
46        let x_bytes = FieldBytes::try_from(x_bytes).map_err(|_| Error::new())?;
47        Self::from_bytes(&x_bytes)
48    }
49
50    /// Borrow the inner [`AffinePoint`] this type wraps.
51    #[must_use]
52    pub fn as_affine(&self) -> &AffinePoint {
53        self.inner.as_affine()
54    }
55
56    /// Serialize as bytes.
57    #[must_use]
58    pub fn to_bytes(&self) -> FieldBytes {
59        self.as_affine().x.to_bytes()
60    }
61
62    /// Compute Schnorr signature.
63    ///
64    /// <div class="warning">
65    /// <b>Warning<b>
66    ///
67    /// This is a low-level interface intended only for unusual use cases involving verifying
68    /// pre-hashed messages, or "raw" messages where the message is not hashed at all prior to being
69    /// used to generate the Schnorr signature.
70    ///
71    /// The preferred interfaces are the [`DigestVerifier`] or [`PrehashVerifier`] traits.
72    /// </div>
73    ///
74    /// # Errors
75    /// Returns [`Error`] if `signature` is not valid for `message`.
76    pub fn verify_raw(&self, message: &[u8], signature: &Signature) -> Result<()> {
77        let (r, s) = signature.split();
78
79        let e = <Scalar as Reduce<FieldBytes>>::reduce(
80            &tagged_hash(CHALLENGE_TAG)
81                .chain_update(signature.r.to_bytes())
82                .chain_update(self.to_bytes())
83                .chain_update(message)
84                .finalize(),
85        );
86
87        let R = ProjectivePoint::mul_by_generator_and_mul_add_vartime(
88            s,
89            &(-e),
90            &self.inner.to_projective(),
91        )
92        .to_affine();
93
94        if R.is_identity().into() || R.y.normalize().is_odd().into() || R.x.normalize() != *r {
95            return Err(Error::new());
96        }
97
98        Ok(())
99    }
100}
101
102//
103// `*Verifier` trait impls
104//
105
106impl<D> DigestVerifier<D, Signature> for VerifyingKey
107where
108    D: Digest<OutputSize = U32> + Update,
109{
110    fn verify_digest<F: Fn(&mut D) -> Result<()>>(
111        &self,
112        f: F,
113        signature: &Signature,
114    ) -> Result<()> {
115        let mut digest = D::new();
116        f(&mut digest)?;
117        self.verify_prehash(&digest.finalize(), signature)
118    }
119}
120
121impl PrehashVerifier<Signature> for VerifyingKey {
122    fn verify_prehash(&self, prehash: &[u8], signature: &Signature) -> Result<()> {
123        self.verify_raw(prehash, signature)
124    }
125}
126
127impl Verifier<Signature> for VerifyingKey {
128    fn verify(&self, msg: &[u8], signature: &Signature) -> Result<()> {
129        self.multipart_verify(&[msg], signature)
130    }
131}
132
133impl MultipartVerifier<Signature> for VerifyingKey {
134    fn multipart_verify(&self, msg: &[&[u8]], signature: &Signature) -> Result<()> {
135        self.verify_digest(
136            |digest: &mut Sha256| {
137                msg.iter().for_each(|&slice| Update::update(digest, slice));
138                Ok(())
139            },
140            signature,
141        )
142    }
143}
144
145//
146// Other trait impls
147//
148
149impl From<VerifyingKey> for AffinePoint {
150    fn from(vk: VerifyingKey) -> AffinePoint {
151        *vk.as_affine()
152    }
153}
154
155impl From<&VerifyingKey> for AffinePoint {
156    fn from(vk: &VerifyingKey) -> AffinePoint {
157        *vk.as_affine()
158    }
159}
160
161impl From<VerifyingKey> for PublicKey {
162    fn from(vk: VerifyingKey) -> PublicKey {
163        vk.inner
164    }
165}
166
167impl From<&VerifyingKey> for PublicKey {
168    fn from(vk: &VerifyingKey) -> PublicKey {
169        vk.inner
170    }
171}
172
173impl TryFrom<AffinePoint> for VerifyingKey {
174    type Error = Error;
175
176    fn try_from(mut point: AffinePoint) -> Result<VerifyingKey> {
177        if point.y.normalize().is_odd().into() {
178            point = -point;
179        }
180
181        PublicKey::try_from(point)
182            .map_err(|_| Error::new())?
183            .try_into()
184    }
185}
186
187impl TryFrom<PublicKey> for VerifyingKey {
188    type Error = Error;
189
190    fn try_from(public_key: PublicKey) -> Result<VerifyingKey> {
191        if public_key.as_affine().y.normalize().is_even().into() {
192            Ok(Self { inner: public_key })
193        } else {
194            Err(Error::new())
195        }
196    }
197}
198
199impl TryFrom<&PublicKey> for VerifyingKey {
200    type Error = Error;
201
202    fn try_from(public_key: &PublicKey) -> Result<VerifyingKey> {
203        Self::try_from(*public_key)
204    }
205}
206
207impl TryFrom<&[u8]> for VerifyingKey {
208    type Error = Error;
209
210    fn try_from(x_bytes: &[u8]) -> Result<VerifyingKey> {
211        Self::from_slice(x_bytes)
212    }
213}
214
215#[cfg(feature = "serde")]
216impl Serialize for VerifyingKey {
217    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
218    where
219        S: ser::Serializer,
220    {
221        self.inner.serialize(serializer)
222    }
223}
224
225#[cfg(feature = "serde")]
226impl<'de> Deserialize<'de> for VerifyingKey {
227    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
228    where
229        D: de::Deserializer<'de>,
230    {
231        VerifyingKey::try_from(PublicKey::deserialize(deserializer)?).map_err(de::Error::custom)
232    }
233}