defuse_crypto/curve/
p256.rs1use crate::{CryptoHash, Curve, VerifiableCurve};
2use generic_array::GenericArray;
3use p256::{
4 EncodedPoint,
5 ecdsa::{Signature, VerifyingKey, signature::hazmat::PrehashVerifier},
6 elliptic_curve::scalar::IsHigh,
7};
8
9pub struct P256;
10
11impl Curve for P256 {
12 type PublicKey = [u8; 33];
14
15 type Signature = [u8; 64];
17
18 type Message = CryptoHash;
20
21 type VerifyingKey = Self::PublicKey;
22}
23
24impl VerifiableCurve for P256 {
25 fn verify(
26 signature: &Self::Signature,
27 prehashed: &Self::Message,
28 public_key: &Self::VerifyingKey,
29 ) -> Option<Self::PublicKey> {
30 let signature =
32 Signature::from_bytes(GenericArray::from_slice(signature).as_0_14()).ok()?;
33
34 if signature.s().is_high().into() {
35 return None;
37 }
38
39 let verifying_key = VerifyingKey::from_sec1_bytes(public_key).ok()?;
41
42 verifying_key
44 .verify_prehash(prehashed, &signature)
45 .is_ok()
46 .then_some(public_key)
47 .copied()
48 }
49}
50
51#[cfg_attr(any(feature = "arbitrary", test), derive(arbitrary::Arbitrary))]
53#[cfg_attr(
54 feature = "serde",
55 derive(::serde_with::SerializeDisplay, ::serde_with::DeserializeFromStr),
56 cfg_attr(feature = "abi", derive(::schemars::JsonSchema))
57)]
58#[cfg_attr(
59 feature = "borsh",
60 derive(::borsh::BorshSerialize, ::borsh::BorshDeserialize),
61 cfg_attr(feature = "abi", derive(::borsh::BorshSchema))
62)]
63#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
64#[repr(transparent)]
65pub struct P256CompressedPublicKey(
66 #[cfg_attr(all(feature = "abi", feature = "serde"), schemars(with = "String"))]
68 pub <P256 as Curve>::PublicKey,
69);
70
71#[cfg_attr(any(feature = "arbitrary", test), derive(arbitrary::Arbitrary))]
73#[cfg_attr(
74 feature = "borsh",
75 derive(::borsh::BorshSerialize, ::borsh::BorshDeserialize),
76 cfg_attr(feature = "abi", derive(::borsh::BorshSchema))
77)]
78#[cfg_attr(
79 feature = "serde",
80 derive(::serde_with::SerializeDisplay, ::serde_with::DeserializeFromStr),
81 cfg_attr(feature = "abi", derive(::schemars::JsonSchema))
82)]
83#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
84#[repr(transparent)]
85pub struct P256UncompressedPublicKey(
86 #[cfg_attr(all(feature = "abi", feature = "serde"), schemars(with = "String"))] pub [u8; 64],
88);
89
90#[cfg_attr(any(feature = "arbitrary", test), derive(arbitrary::Arbitrary))]
91#[cfg_attr(
92 feature = "borsh",
93 derive(::borsh::BorshSerialize, ::borsh::BorshDeserialize),
94 cfg_attr(feature = "abi", derive(::borsh::BorshSchema))
95)]
96#[cfg_attr(
97 feature = "serde",
98 derive(::serde_with::SerializeDisplay, ::serde_with::DeserializeFromStr),
99 cfg_attr(feature = "abi", derive(::schemars::JsonSchema))
100)]
101#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
102#[repr(transparent)]
103pub struct P256Signature(
104 #[cfg_attr(all(feature = "abi", feature = "serde"), schemars(with = "String"))]
106 pub <P256 as Curve>::Signature,
107);
108
109#[cfg(feature = "parse")]
110const _: () = {
111 use crate::{CurveType, ParseCurveError, TypedCurve};
112 use core::fmt::{self, Debug, Display};
113 use std::str::FromStr;
114
115 impl TypedCurve for P256 {
116 const CURVE_TYPE: CurveType = CurveType::P256;
117 }
118
119 impl Debug for P256CompressedPublicKey {
120 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
121 Display::fmt(self, f)
122 }
123 }
124
125 impl Display for P256CompressedPublicKey {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 f.write_str(&<P256 as TypedCurve>::to_base58(self.0))
128 }
129 }
130
131 impl FromStr for P256CompressedPublicKey {
132 type Err = ParseCurveError;
133
134 fn from_str(s: &str) -> Result<Self, Self::Err> {
135 P256::parse_base58(s).map(Self)
136 }
137 }
138
139 impl Debug for P256UncompressedPublicKey {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 Display::fmt(self, f)
142 }
143 }
144
145 impl Display for P256UncompressedPublicKey {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 f.write_str(&<P256 as TypedCurve>::to_base58(self.0))
148 }
149 }
150
151 impl FromStr for P256UncompressedPublicKey {
152 type Err = ParseCurveError;
153
154 fn from_str(s: &str) -> Result<Self, Self::Err> {
155 P256::parse_base58(s).map(Self)
156 }
157 }
158
159 impl Debug for P256Signature {
160 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161 Display::fmt(self, f)
162 }
163 }
164
165 impl Display for P256Signature {
166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 f.write_str(&<P256 as TypedCurve>::to_base58(self.0))
168 }
169 }
170
171 impl FromStr for P256Signature {
172 type Err = ParseCurveError;
173
174 fn from_str(s: &str) -> Result<Self, Self::Err> {
175 P256::parse_base58(s).map(Self)
176 }
177 }
178};
179
180pub fn compress_public_key(public_key: P256UncompressedPublicKey) -> P256CompressedPublicKey {
184 EncodedPoint::from_untagged_bytes(GenericArray::from_array(public_key.0).as_0_14())
185 .compress()
186 .as_bytes()
187 .try_into()
188 .map_or_else(|_| unreachable!(), P256CompressedPublicKey)
189}