k256/schnorr/
verifying.rs1use super::{tagged_hash, Signature, CHALLENGE_TAG};
4use crate::{AffinePoint, FieldBytes, ProjectivePoint, PublicKey, Scalar};
5use elliptic_curve::{
6 bigint::U256,
7 group::prime::PrimeCurveAffine,
8 ops::{LinearCombination, Reduce},
9 point::DecompactPoint,
10};
11use sha2::{
12 digest::{consts::U32, FixedOutput},
13 Digest, Sha256,
14};
15use signature::{hazmat::PrehashVerifier, DigestVerifier, Error, Result, Verifier};
16
17#[cfg(feature = "serde")]
18use serdect::serde::{de, ser, Deserialize, Serialize};
19
20#[derive(Copy, Clone, Debug, Eq, PartialEq)]
22pub struct VerifyingKey {
23 pub(super) inner: PublicKey,
25}
26
27impl VerifyingKey {
28 pub fn as_affine(&self) -> &AffinePoint {
30 self.inner.as_affine()
31 }
32
33 pub fn to_bytes(&self) -> FieldBytes {
35 self.as_affine().x.to_bytes()
36 }
37
38 pub fn verify_raw(
49 &self,
50 message: &[u8],
51 signature: &Signature,
52 ) -> core::result::Result<(), Error> {
53 let (r, s) = signature.split();
54
55 let e = <Scalar as Reduce<U256>>::reduce_bytes(
56 &tagged_hash(CHALLENGE_TAG)
57 .chain_update(signature.r.to_bytes())
58 .chain_update(self.to_bytes())
59 .chain_update(message)
60 .finalize(),
61 );
62
63 let R = ProjectivePoint::lincomb(
64 &ProjectivePoint::GENERATOR,
65 s,
66 &self.inner.to_projective(),
67 &-e,
68 )
69 .to_affine();
70
71 if R.is_identity().into() || R.y.normalize().is_odd().into() || R.x.normalize() != *r {
72 return Err(Error::new());
73 }
74
75 Ok(())
76 }
77
78 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
80 let maybe_affine_point = AffinePoint::decompact(FieldBytes::from_slice(bytes));
81 let affine_point = Option::from(maybe_affine_point).ok_or_else(Error::new)?;
82 PublicKey::from_affine(affine_point)
83 .map_err(|_| Error::new())?
84 .try_into()
85 }
86}
87
88impl<D> DigestVerifier<D, Signature> for VerifyingKey
93where
94 D: Digest + FixedOutput<OutputSize = U32>,
95{
96 fn verify_digest(&self, digest: D, signature: &Signature) -> Result<()> {
97 self.verify_prehash(digest.finalize_fixed().as_slice(), signature)
98 }
99}
100
101impl PrehashVerifier<Signature> for VerifyingKey {
102 fn verify_prehash(
103 &self,
104 prehash: &[u8],
105 signature: &Signature,
106 ) -> core::result::Result<(), Error> {
107 self.verify_raw(prehash, signature)
108 }
109}
110
111impl Verifier<Signature> for VerifyingKey {
112 fn verify(&self, msg: &[u8], signature: &Signature) -> Result<()> {
113 self.verify_digest(Sha256::new_with_prefix(msg), signature)
114 }
115}
116
117impl From<VerifyingKey> for AffinePoint {
122 fn from(vk: VerifyingKey) -> AffinePoint {
123 *vk.as_affine()
124 }
125}
126
127impl From<&VerifyingKey> for AffinePoint {
128 fn from(vk: &VerifyingKey) -> AffinePoint {
129 *vk.as_affine()
130 }
131}
132
133impl From<VerifyingKey> for PublicKey {
134 fn from(vk: VerifyingKey) -> PublicKey {
135 vk.inner
136 }
137}
138
139impl From<&VerifyingKey> for PublicKey {
140 fn from(vk: &VerifyingKey) -> PublicKey {
141 vk.inner
142 }
143}
144
145impl TryFrom<PublicKey> for VerifyingKey {
146 type Error = Error;
147
148 fn try_from(public_key: PublicKey) -> Result<VerifyingKey> {
149 if public_key.as_affine().y.normalize().is_even().into() {
150 Ok(Self { inner: public_key })
151 } else {
152 Err(Error::new())
153 }
154 }
155}
156
157impl TryFrom<&PublicKey> for VerifyingKey {
158 type Error = Error;
159
160 fn try_from(public_key: &PublicKey) -> Result<VerifyingKey> {
161 Self::try_from(*public_key)
162 }
163}
164
165#[cfg(feature = "serde")]
166impl Serialize for VerifyingKey {
167 fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
168 where
169 S: ser::Serializer,
170 {
171 self.inner.serialize(serializer)
172 }
173}
174
175#[cfg(feature = "serde")]
176impl<'de> Deserialize<'de> for VerifyingKey {
177 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
178 where
179 D: de::Deserializer<'de>,
180 {
181 VerifyingKey::try_from(PublicKey::deserialize(deserializer)?).map_err(de::Error::custom)
182 }
183}