1use crate::SignatureError;
2use p256::ecdsa::SigningKey;
3use p256::ecdsa::VerifyingKey;
4use p256::elliptic_curve::group::GroupEncoding;
5use signature::Signer;
6use signature::Verifier;
7use sui_sdk_types::Secp256r1PublicKey;
8use sui_sdk_types::Secp256r1Signature;
9use sui_sdk_types::SignatureScheme;
10use sui_sdk_types::SimpleSignature;
11use sui_sdk_types::UserSignature;
12
13#[derive(Clone)]
14pub struct Secp256r1PrivateKey(SigningKey);
15
16impl std::fmt::Debug for Secp256r1PrivateKey {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 f.debug_tuple("Secp256r1PrivateKey")
19 .field(&"__elided__")
20 .finish()
21 }
22}
23
24#[cfg(test)]
25impl proptest::arbitrary::Arbitrary for Secp256r1PrivateKey {
26 type Parameters = ();
27 type Strategy = proptest::strategy::BoxedStrategy<Self>;
28 fn arbitrary_with(_: Self::Parameters) -> Self::Strategy {
29 use proptest::strategy::Strategy;
30
31 proptest::arbitrary::any::<[u8; Self::LENGTH]>()
32 .prop_map(Self::new)
33 .boxed()
34 }
35}
36
37impl Secp256r1PrivateKey {
38 pub const LENGTH: usize = 32;
40
41 pub fn new(bytes: [u8; Self::LENGTH]) -> Self {
42 Self(SigningKey::from_bytes(&bytes.into()).unwrap())
43 }
44
45 pub fn scheme(&self) -> SignatureScheme {
46 SignatureScheme::Secp256r1
47 }
48
49 pub fn verifying_key(&self) -> Secp256r1VerifyingKey {
50 let verifying_key = self.0.verifying_key();
51 Secp256r1VerifyingKey(*verifying_key)
52 }
53
54 pub fn public_key(&self) -> Secp256r1PublicKey {
55 Secp256r1PublicKey::new(self.0.verifying_key().as_ref().to_bytes().into())
56 }
57
58 pub fn generate<R>(mut rng: R) -> Self
59 where
60 R: rand_core::RngCore + rand_core::CryptoRng,
61 {
62 let mut buf: [u8; Self::LENGTH] = [0; Self::LENGTH];
63 rng.fill_bytes(&mut buf);
64 Self::new(buf)
65 }
66
67 #[cfg(feature = "pem")]
68 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
69 pub fn from_der(bytes: &[u8]) -> Result<Self, SignatureError> {
71 p256::pkcs8::DecodePrivateKey::from_pkcs8_der(bytes)
72 .map(Self)
73 .map_err(SignatureError::from_source)
74 }
75
76 #[cfg(feature = "pem")]
77 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
78 pub fn to_der(&self) -> Result<Vec<u8>, SignatureError> {
80 use p256::pkcs8::EncodePrivateKey;
81
82 self.0
83 .to_pkcs8_der()
84 .map_err(SignatureError::from_source)
85 .map(|der| der.as_bytes().to_owned())
86 }
87
88 #[cfg(feature = "pem")]
89 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
90 pub fn from_pem(s: &str) -> Result<Self, SignatureError> {
92 p256::pkcs8::DecodePrivateKey::from_pkcs8_pem(s)
93 .map(Self)
94 .map_err(SignatureError::from_source)
95 }
96
97 #[cfg(feature = "pem")]
98 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
99 pub fn to_pem(&self) -> Result<String, SignatureError> {
101 use pkcs8::EncodePrivateKey;
102
103 self.0
104 .to_pkcs8_pem(pkcs8::LineEnding::default())
105 .map_err(SignatureError::from_source)
106 .map(|pem| (*pem).to_owned())
107 }
108
109 #[cfg(feature = "pem")]
110 pub(crate) fn from_p256(private_key: SigningKey) -> Self {
111 Self(private_key)
112 }
113}
114
115impl Signer<Secp256r1Signature> for Secp256r1PrivateKey {
116 fn try_sign(&self, message: &[u8]) -> Result<Secp256r1Signature, SignatureError> {
117 let signature: p256::ecdsa::Signature = self.0.try_sign(message)?;
118 Ok(Secp256r1Signature::new(signature.to_bytes().into()))
119 }
120}
121
122impl Signer<SimpleSignature> for Secp256r1PrivateKey {
123 fn try_sign(&self, msg: &[u8]) -> Result<SimpleSignature, SignatureError> {
124 <Self as Signer<Secp256r1Signature>>::try_sign(self, msg).map(|signature| {
125 SimpleSignature::Secp256r1 {
126 signature,
127 public_key: self.public_key(),
128 }
129 })
130 }
131}
132
133impl Signer<UserSignature> for Secp256r1PrivateKey {
134 fn try_sign(&self, msg: &[u8]) -> Result<UserSignature, SignatureError> {
135 <Self as Signer<SimpleSignature>>::try_sign(self, msg).map(UserSignature::Simple)
136 }
137}
138
139#[derive(Debug, Clone, Eq, PartialEq)]
140pub struct Secp256r1VerifyingKey(VerifyingKey);
141
142impl Secp256r1VerifyingKey {
143 pub fn new(public_key: &Secp256r1PublicKey) -> Result<Self, SignatureError> {
144 VerifyingKey::try_from(public_key.inner().as_ref()).map(Self)
145 }
146
147 pub fn public_key(&self) -> Secp256r1PublicKey {
148 Secp256r1PublicKey::new(self.0.as_ref().to_bytes().into())
149 }
150
151 #[cfg(feature = "pem")]
152 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
153 pub fn from_der(bytes: &[u8]) -> Result<Self, SignatureError> {
155 p256::pkcs8::DecodePublicKey::from_public_key_der(bytes)
156 .map(Self)
157 .map_err(SignatureError::from_source)
158 }
159
160 #[cfg(feature = "pem")]
161 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
162 pub fn to_der(&self) -> Result<Vec<u8>, SignatureError> {
164 use pkcs8::EncodePublicKey;
165
166 self.0
167 .to_public_key_der()
168 .map_err(SignatureError::from_source)
169 .map(|der| der.into_vec())
170 }
171
172 #[cfg(feature = "pem")]
173 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
174 pub fn from_pem(s: &str) -> Result<Self, SignatureError> {
176 p256::pkcs8::DecodePublicKey::from_public_key_pem(s)
177 .map(Self)
178 .map_err(SignatureError::from_source)
179 }
180
181 #[cfg(feature = "pem")]
182 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
183 pub fn to_pem(&self) -> Result<String, SignatureError> {
185 use pkcs8::EncodePublicKey;
186
187 self.0
188 .to_public_key_pem(pkcs8::LineEnding::default())
189 .map_err(SignatureError::from_source)
190 }
191
192 #[cfg(feature = "pem")]
193 pub(crate) fn from_p256(verifying_key: VerifyingKey) -> Self {
194 Self(verifying_key)
195 }
196}
197
198impl Verifier<Secp256r1Signature> for Secp256r1VerifyingKey {
199 fn verify(&self, message: &[u8], signature: &Secp256r1Signature) -> Result<(), SignatureError> {
200 let signature = p256::ecdsa::Signature::from_bytes(signature.inner().into())?;
201 self.0.verify(message, &signature)
202 }
203}
204
205impl Verifier<SimpleSignature> for Secp256r1VerifyingKey {
206 fn verify(&self, message: &[u8], signature: &SimpleSignature) -> Result<(), SignatureError> {
207 let SimpleSignature::Secp256r1 {
208 signature,
209 public_key,
210 } = signature
211 else {
212 return Err(SignatureError::from_source("not a secp256r1 signature"));
213 };
214
215 if public_key.inner() != self.public_key().inner() {
216 return Err(SignatureError::from_source(
217 "public_key in signature does not match",
218 ));
219 }
220
221 <Self as Verifier<Secp256r1Signature>>::verify(self, message, signature)
222 }
223}
224
225impl Verifier<UserSignature> for Secp256r1VerifyingKey {
226 fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
227 let UserSignature::Simple(signature) = signature else {
228 return Err(SignatureError::from_source("not a secp256r1 signature"));
229 };
230
231 <Self as Verifier<SimpleSignature>>::verify(self, message, signature)
232 }
233}
234
235#[derive(Default, Clone, Debug)]
236pub struct Secp256r1Verifier {}
237
238impl Secp256r1Verifier {
239 pub fn new() -> Self {
240 Self {}
241 }
242}
243
244impl Verifier<SimpleSignature> for Secp256r1Verifier {
245 fn verify(&self, message: &[u8], signature: &SimpleSignature) -> Result<(), SignatureError> {
246 let SimpleSignature::Secp256r1 {
247 signature,
248 public_key,
249 } = signature
250 else {
251 return Err(SignatureError::from_source("not a secp256r1 signature"));
252 };
253
254 let verifying_key = Secp256r1VerifyingKey::new(public_key)?;
255
256 verifying_key.verify(message, signature)
257 }
258}
259
260impl Verifier<UserSignature> for Secp256r1Verifier {
261 fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
262 let UserSignature::Simple(signature) = signature else {
263 return Err(SignatureError::from_source("not a secp256r1 signature"));
264 };
265
266 <Self as Verifier<SimpleSignature>>::verify(self, message, signature)
267 }
268}
269
270#[cfg(test)]
271mod test {
272 use super::*;
273 use crate::SuiSigner;
274 use crate::SuiVerifier;
275 use sui_sdk_types::PersonalMessage;
276 use test_strategy::proptest;
277
278 #[cfg(target_arch = "wasm32")]
279 use wasm_bindgen_test::wasm_bindgen_test as test;
280
281 #[proptest]
292 fn personal_message_signing(signer: Secp256r1PrivateKey, message: Vec<u8>) {
293 let message = PersonalMessage(message.into());
294 let signature = signer.sign_personal_message(&message).unwrap();
295 let verifying_key = signer.verifying_key();
296 verifying_key
297 .verify_personal_message(&message, &signature)
298 .unwrap();
299
300 let verifier = Secp256r1Verifier::default();
301 verifier
302 .verify_personal_message(&message, &signature)
303 .unwrap();
304 }
305
306 #[test]
307 fn personal_message_signing_fixture() {
308 let key = [
309 167, 44, 116, 0, 51, 221, 254, 179, 210, 44, 93, 196, 125, 155, 85, 94, 29, 41, 13, 60,
310 59, 132, 69, 84, 176, 217, 77, 49, 25, 113, 118, 125,
311 ];
312 let signer = Secp256r1PrivateKey::new(key);
313
314 let message = PersonalMessage(b"hello".into());
315 let sig = signer.sign_personal_message(&message).unwrap();
316 let external_sig = "AlqWPdkIE2bZAUquKv2Tdh9i+Ih+rVSQXH/YsgvwkmeOJR0YLjL/kadivoPtiQkvZBQ1ZI8eDZxe8SaLniwoT88Dh+/vAuGf1UrouFTdefpBEWn3apy8x3EexN5c5ESzGDc=";
317 let b64 = sig.to_base64();
318 assert_eq!(external_sig, b64);
319 }
320}