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