1use crate::SignatureError;
2use signature::Verifier;
3use sui_sdk_types::SimpleSignature;
4use sui_sdk_types::UserSignature;
5
6pub struct SimpleVerifier;
7
8impl Verifier<SimpleSignature> for SimpleVerifier {
9 #[allow(unused_variables)]
10 fn verify(&self, message: &[u8], signature: &SimpleSignature) -> Result<(), SignatureError> {
11 match signature {
12 #[cfg(feature = "ed25519")]
13 SimpleSignature::Ed25519 {
14 signature,
15 public_key,
16 } => {
17 let verifying_key = crate::ed25519::Ed25519VerifyingKey::new(public_key)?;
18 verifying_key.verify(message, signature)
19 }
20 #[cfg(not(feature = "ed25519"))]
21 SimpleSignature::Ed25519 { .. } => Err(SignatureError::from_source(
22 "support for ed25519 is not enabled",
23 )),
24 #[cfg(feature = "secp256k1")]
25 SimpleSignature::Secp256k1 {
26 signature,
27 public_key,
28 } => {
29 let verifying_key = crate::secp256k1::Secp256k1VerifyingKey::new(public_key)?;
30 verifying_key.verify(message, signature)
31 }
32 #[cfg(not(feature = "secp256k1"))]
33 SimpleSignature::Secp256k1 { .. } => Err(SignatureError::from_source(
34 "support for secp256k1 is not enabled",
35 )),
36 #[cfg(feature = "secp256r1")]
37 SimpleSignature::Secp256r1 {
38 signature,
39 public_key,
40 } => {
41 let verifying_key = crate::secp256r1::Secp256r1VerifyingKey::new(public_key)?;
42 verifying_key.verify(message, signature)
43 }
44 #[cfg(not(feature = "secp256r1"))]
45 SimpleSignature::Secp256r1 { .. } => Err(SignatureError::from_source(
46 "support for secp256r1 is not enabled",
47 )),
48 #[cfg(feature = "mldsa65")]
49 SimpleSignature::MlDsa65 {
50 signature,
51 public_key,
52 } => {
53 let verifying_key = crate::mldsa65::MlDsa65VerifyingKey::new(public_key)?;
54 verifying_key.verify(message, signature.as_ref())
55 }
56 #[cfg(not(feature = "mldsa65"))]
57 SimpleSignature::MlDsa65 { .. } => Err(SignatureError::from_source(
58 "support for mldsa65 is not enabled",
59 )),
60 _ => Err(SignatureError::from_source("unknown signature scheme")),
61 }
62 }
63}
64
65impl Verifier<UserSignature> for SimpleVerifier {
66 fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
67 let UserSignature::Simple(signature) = signature else {
68 return Err(SignatureError::from_source("not a simple signature"));
69 };
70
71 <Self as Verifier<SimpleSignature>>::verify(self, message, signature)
72 }
73}
74
75#[cfg(any(
76 feature = "ed25519",
77 feature = "secp256r1",
78 feature = "secp256k1",
79 feature = "mldsa65",
80))]
81#[cfg_attr(
82 doc_cfg,
83 doc(cfg(any(
84 feature = "ed25519",
85 feature = "secp256r1",
86 feature = "secp256k1",
87 feature = "mldsa65",
88 )))
89)]
90#[rustfmt::skip]
91pub use keypair::{SimpleKeypair, SimpleVerifiyingKey};
92
93#[cfg(any(
94 feature = "ed25519",
95 feature = "secp256r1",
96 feature = "secp256k1",
97 feature = "mldsa65",
98))]
99#[cfg_attr(
100 doc_cfg,
101 doc(cfg(any(
102 feature = "ed25519",
103 feature = "secp256r1",
104 feature = "secp256k1",
105 feature = "mldsa65",
106 )))
107)]
108mod keypair {
109 use crate::SignatureError;
110 use signature::Signer;
111 use signature::Verifier;
112 use sui_sdk_types::MultisigMemberPublicKey;
113 use sui_sdk_types::SignatureScheme;
114 use sui_sdk_types::SimpleSignature;
115 use sui_sdk_types::UserSignature;
116
117 #[derive(Debug, Clone)]
118 pub struct SimpleKeypair {
119 inner: InnerKeypair,
120 }
121
122 #[derive(Debug, Clone)]
123 enum InnerKeypair {
124 #[cfg(feature = "ed25519")]
125 Ed25519(crate::ed25519::Ed25519PrivateKey),
126 #[cfg(feature = "secp256k1")]
127 Secp256k1(crate::secp256k1::Secp256k1PrivateKey),
128 #[cfg(feature = "secp256r1")]
129 Secp256r1(crate::secp256r1::Secp256r1PrivateKey),
130 #[cfg(feature = "mldsa65")]
131 MlDsa65(crate::mldsa65::MlDsa65PrivateKey),
132 }
133
134 impl SimpleKeypair {
135 pub fn scheme(&self) -> SignatureScheme {
136 match &self.inner {
137 #[cfg(feature = "ed25519")]
138 InnerKeypair::Ed25519(private_key) => private_key.scheme(),
139 #[cfg(feature = "secp256k1")]
140 InnerKeypair::Secp256k1(private_key) => private_key.scheme(),
141 #[cfg(feature = "secp256r1")]
142 InnerKeypair::Secp256r1(private_key) => private_key.scheme(),
143 #[cfg(feature = "mldsa65")]
144 InnerKeypair::MlDsa65(private_key) => private_key.scheme(),
145 }
146 }
147
148 pub fn verifying_key(&self) -> SimpleVerifiyingKey {
149 let verifying_key = match &self.inner {
150 #[cfg(feature = "ed25519")]
151 InnerKeypair::Ed25519(private_key) => {
152 InnerVerifyingKey::Ed25519(private_key.verifying_key())
153 }
154 #[cfg(feature = "secp256k1")]
155 InnerKeypair::Secp256k1(private_key) => {
156 InnerVerifyingKey::Secp256k1(private_key.verifying_key())
157 }
158 #[cfg(feature = "secp256r1")]
159 InnerKeypair::Secp256r1(private_key) => {
160 InnerVerifyingKey::Secp256r1(private_key.verifying_key())
161 }
162 #[cfg(feature = "mldsa65")]
163 InnerKeypair::MlDsa65(private_key) => {
164 InnerVerifyingKey::MlDsa65(private_key.verifying_key())
165 }
166 };
167
168 SimpleVerifiyingKey {
169 inner: verifying_key,
170 }
171 }
172
173 pub fn public_key(&self) -> MultisigMemberPublicKey {
174 self.verifying_key().public_key()
175 }
176
177 #[cfg(feature = "pem")]
178 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
179 pub fn from_der(bytes: &[u8]) -> Result<Self, SignatureError> {
181 let private_key =
182 pkcs8::PrivateKeyInfo::try_from(bytes).map_err(SignatureError::from_source)?;
183
184 match private_key
185 .algorithm
186 .oids()
187 .map_err(SignatureError::from_source)?
188 {
189 #[cfg(feature = "ed25519")]
190 (ed25519_dalek::pkcs8::ALGORITHM_OID, None) => private_key
191 .try_into()
192 .map(crate::ed25519::Ed25519PrivateKey::from_dalek)
193 .map(InnerKeypair::Ed25519)
194 .map_err(SignatureError::from_source),
195
196 #[cfg(feature = "secp256r1")]
197 (
198 p256::elliptic_curve::ALGORITHM_OID,
199 Some(<p256::NistP256 as pkcs8::AssociatedOid>::OID),
200 ) => private_key
201 .try_into()
202 .map(crate::secp256r1::Secp256r1PrivateKey::from_p256)
203 .map(InnerKeypair::Secp256r1)
204 .map_err(SignatureError::from_source),
205
206 #[cfg(feature = "secp256k1")]
207 (
208 k256::elliptic_curve::ALGORITHM_OID,
209 Some(<k256::Secp256k1 as pkcs8::AssociatedOid>::OID),
210 ) => private_key
211 .try_into()
212 .map(crate::secp256k1::Secp256k1PrivateKey::from_k256)
213 .map(InnerKeypair::Secp256k1)
214 .map_err(SignatureError::from_source),
215
216 _ => Err(SignatureError::from_source(
217 "unsupported or invalid private key type",
218 )),
219 }
220 .map(|inner| Self { inner })
221 }
222
223 #[cfg(feature = "pem")]
224 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
225 pub fn to_der(&self) -> Result<Vec<u8>, SignatureError> {
227 match &self.inner {
228 #[cfg(feature = "ed25519")]
229 InnerKeypair::Ed25519(private_key) => private_key.to_der(),
230 #[cfg(feature = "secp256k1")]
231 InnerKeypair::Secp256k1(private_key) => private_key.to_der(),
232 #[cfg(feature = "secp256r1")]
233 InnerKeypair::Secp256r1(private_key) => private_key.to_der(),
234 #[cfg(feature = "mldsa65")]
235 InnerKeypair::MlDsa65(_) => Err(SignatureError::from_source(
236 "pem encoding is not supported for mldsa65",
237 )),
238 }
239 }
240
241 #[cfg(feature = "pem")]
242 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
243 pub fn from_pem(s: &str) -> Result<Self, SignatureError> {
245 use pkcs8::der::pem::PemLabel;
246
247 let (label, doc) =
248 pkcs8::SecretDocument::from_pem(s).map_err(SignatureError::from_source)?;
249 pkcs8::PrivateKeyInfo::validate_pem_label(label)
250 .map_err(SignatureError::from_source)?;
251 Self::from_der(doc.as_bytes())
252 }
253
254 #[cfg(feature = "pem")]
255 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
256 pub fn to_pem(&self) -> Result<String, SignatureError> {
258 match &self.inner {
259 #[cfg(feature = "ed25519")]
260 InnerKeypair::Ed25519(private_key) => private_key.to_pem(),
261 #[cfg(feature = "secp256k1")]
262 InnerKeypair::Secp256k1(private_key) => private_key.to_pem(),
263 #[cfg(feature = "secp256r1")]
264 InnerKeypair::Secp256r1(private_key) => private_key.to_pem(),
265 #[cfg(feature = "mldsa65")]
266 InnerKeypair::MlDsa65(_) => Err(SignatureError::from_source(
267 "pem encoding is not supported for mldsa65",
268 )),
269 }
270 }
271
272 fn from_flagged_key_bytes(
278 scheme: SignatureScheme,
279 key: Vec<u8>,
280 ) -> Result<Self, SignatureError> {
281 let inner = match scheme {
282 #[cfg(feature = "ed25519")]
283 SignatureScheme::Ed25519 => InnerKeypair::Ed25519(
284 crate::ed25519::Ed25519PrivateKey::from_flagged_key_bytes(scheme, key)?,
285 ),
286 #[cfg(feature = "secp256k1")]
287 SignatureScheme::Secp256k1 => InnerKeypair::Secp256k1(
288 crate::secp256k1::Secp256k1PrivateKey::from_flagged_key_bytes(scheme, key)?,
289 ),
290 #[cfg(feature = "secp256r1")]
291 SignatureScheme::Secp256r1 => InnerKeypair::Secp256r1(
292 crate::secp256r1::Secp256r1PrivateKey::from_flagged_key_bytes(scheme, key)?,
293 ),
294 #[cfg(feature = "mldsa65")]
295 SignatureScheme::MlDsa65 => InnerKeypair::MlDsa65(
296 crate::mldsa65::MlDsa65PrivateKey::from_flagged_key_bytes(scheme, key)?,
297 ),
298 other => {
299 return Err(SignatureError::from_source(format!(
300 "unsupported scheme `{}` in private key encoding",
301 other.name(),
302 )));
303 }
304 };
305 Ok(Self { inner })
306 }
307
308 #[cfg(feature = "bech32")]
309 #[cfg_attr(doc_cfg, doc(cfg(feature = "bech32")))]
310 pub fn from_suiprivkey(s: &str) -> Result<Self, SignatureError> {
316 let (scheme, key) = crate::suipriv::decode(s)?;
317 Self::from_flagged_key_bytes(scheme, key)
318 }
319
320 #[cfg(feature = "bech32")]
321 #[cfg_attr(doc_cfg, doc(cfg(feature = "bech32")))]
322 pub fn to_suiprivkey(&self) -> Result<String, SignatureError> {
324 match &self.inner {
325 #[cfg(feature = "ed25519")]
326 InnerKeypair::Ed25519(private_key) => private_key.to_suiprivkey(),
327 #[cfg(feature = "secp256k1")]
328 InnerKeypair::Secp256k1(private_key) => private_key.to_suiprivkey(),
329 #[cfg(feature = "secp256r1")]
330 InnerKeypair::Secp256r1(private_key) => private_key.to_suiprivkey(),
331 #[cfg(feature = "mldsa65")]
332 InnerKeypair::MlDsa65(private_key) => private_key.to_suiprivkey(),
333 }
334 }
335
336 pub fn from_base64(s: &str) -> Result<Self, SignatureError> {
343 let (scheme, key) = crate::suipriv::decode_base64(s)?;
344 Self::from_flagged_key_bytes(scheme, key)
345 }
346
347 pub fn to_base64(&self) -> String {
351 match &self.inner {
352 #[cfg(feature = "ed25519")]
353 InnerKeypair::Ed25519(private_key) => private_key.to_base64(),
354 #[cfg(feature = "secp256k1")]
355 InnerKeypair::Secp256k1(private_key) => private_key.to_base64(),
356 #[cfg(feature = "secp256r1")]
357 InnerKeypair::Secp256r1(private_key) => private_key.to_base64(),
358 #[cfg(feature = "mldsa65")]
359 InnerKeypair::MlDsa65(private_key) => private_key.to_base64(),
360 }
361 }
362 }
363
364 impl Signer<SimpleSignature> for SimpleKeypair {
365 #[cfg_attr(
375 not(any(feature = "ed25519", feature = "secp256k1", feature = "secp256r1")),
376 allow(unused_variables)
377 )]
378 fn try_sign(&self, message: &[u8]) -> Result<SimpleSignature, SignatureError> {
379 match &self.inner {
380 #[cfg(feature = "ed25519")]
381 InnerKeypair::Ed25519(private_key) => private_key.try_sign(message),
382 #[cfg(feature = "secp256k1")]
383 InnerKeypair::Secp256k1(private_key) => private_key.try_sign(message),
384 #[cfg(feature = "secp256r1")]
385 InnerKeypair::Secp256r1(private_key) => private_key.try_sign(message),
386 #[cfg(feature = "mldsa65")]
387 InnerKeypair::MlDsa65(_) => Err(SignatureError::from_source(
388 "mldsa65 signing requires randomness; sign with RandomizedSigner",
389 )),
390 }
391 }
392 }
393
394 #[cfg(feature = "mldsa65")]
398 #[cfg_attr(doc_cfg, doc(cfg(feature = "mldsa65")))]
399 impl signature::RandomizedSigner<SimpleSignature> for SimpleKeypair {
400 fn try_sign_with_rng(
401 &self,
402 rng: &mut impl rand_core::CryptoRngCore,
403 message: &[u8],
404 ) -> Result<SimpleSignature, SignatureError> {
405 match &self.inner {
406 #[cfg(feature = "ed25519")]
407 InnerKeypair::Ed25519(private_key) => private_key.try_sign(message),
408 #[cfg(feature = "secp256k1")]
409 InnerKeypair::Secp256k1(private_key) => private_key.try_sign(message),
410 #[cfg(feature = "secp256r1")]
411 InnerKeypair::Secp256r1(private_key) => private_key.try_sign(message),
412 InnerKeypair::MlDsa65(private_key) => {
413 signature::RandomizedSigner::try_sign_with_rng(private_key, rng, message)
414 }
415 }
416 }
417 }
418
419 #[cfg(feature = "mldsa65")]
420 #[cfg_attr(doc_cfg, doc(cfg(feature = "mldsa65")))]
421 impl signature::RandomizedSigner<UserSignature> for SimpleKeypair {
422 fn try_sign_with_rng(
423 &self,
424 rng: &mut impl rand_core::CryptoRngCore,
425 msg: &[u8],
426 ) -> Result<UserSignature, SignatureError> {
427 <Self as signature::RandomizedSigner<SimpleSignature>>::try_sign_with_rng(
428 self, rng, msg,
429 )
430 .map(UserSignature::Simple)
431 }
432 }
433
434 impl Signer<UserSignature> for SimpleKeypair {
435 fn try_sign(&self, msg: &[u8]) -> Result<UserSignature, SignatureError> {
436 <Self as Signer<SimpleSignature>>::try_sign(self, msg).map(UserSignature::Simple)
437 }
438 }
439
440 #[cfg(feature = "ed25519")]
441 #[cfg_attr(doc_cfg, doc(cfg(feature = "ed25519")))]
442 impl From<crate::ed25519::Ed25519PrivateKey> for SimpleKeypair {
443 fn from(private_key: crate::ed25519::Ed25519PrivateKey) -> Self {
444 Self {
445 inner: InnerKeypair::Ed25519(private_key),
446 }
447 }
448 }
449
450 #[cfg(feature = "secp256r1")]
451 #[cfg_attr(doc_cfg, doc(cfg(feature = "secp256r1")))]
452 impl From<crate::secp256r1::Secp256r1PrivateKey> for SimpleKeypair {
453 fn from(private_key: crate::secp256r1::Secp256r1PrivateKey) -> Self {
454 Self {
455 inner: InnerKeypair::Secp256r1(private_key),
456 }
457 }
458 }
459
460 #[cfg(feature = "secp256k1")]
461 #[cfg_attr(doc_cfg, doc(cfg(feature = "secp256k1")))]
462 impl From<crate::secp256k1::Secp256k1PrivateKey> for SimpleKeypair {
463 fn from(private_key: crate::secp256k1::Secp256k1PrivateKey) -> Self {
464 Self {
465 inner: InnerKeypair::Secp256k1(private_key),
466 }
467 }
468 }
469
470 #[cfg(feature = "mldsa65")]
471 #[cfg_attr(doc_cfg, doc(cfg(feature = "mldsa65")))]
472 impl From<crate::mldsa65::MlDsa65PrivateKey> for SimpleKeypair {
473 fn from(private_key: crate::mldsa65::MlDsa65PrivateKey) -> Self {
474 Self {
475 inner: InnerKeypair::MlDsa65(private_key),
476 }
477 }
478 }
479
480 #[derive(Debug, Clone, Eq, PartialEq)]
481 pub struct SimpleVerifiyingKey {
482 inner: InnerVerifyingKey,
483 }
484
485 #[derive(Debug, Clone, Eq, PartialEq)]
486 enum InnerVerifyingKey {
487 #[cfg(feature = "ed25519")]
488 Ed25519(crate::ed25519::Ed25519VerifyingKey),
489 #[cfg(feature = "secp256k1")]
490 Secp256k1(crate::secp256k1::Secp256k1VerifyingKey),
491 #[cfg(feature = "secp256r1")]
492 Secp256r1(crate::secp256r1::Secp256r1VerifyingKey),
493 #[cfg(feature = "mldsa65")]
494 MlDsa65(crate::mldsa65::MlDsa65VerifyingKey),
495 }
496
497 impl SimpleVerifiyingKey {
498 pub fn scheme(&self) -> SignatureScheme {
499 match &self.inner {
500 #[cfg(feature = "ed25519")]
501 InnerVerifyingKey::Ed25519(verifying_key) => verifying_key.public_key().scheme(),
502 #[cfg(feature = "secp256k1")]
503 InnerVerifyingKey::Secp256k1(verifying_key) => verifying_key.public_key().scheme(),
504 #[cfg(feature = "secp256r1")]
505 InnerVerifyingKey::Secp256r1(verifying_key) => verifying_key.public_key().scheme(),
506 #[cfg(feature = "mldsa65")]
507 InnerVerifyingKey::MlDsa65(verifying_key) => verifying_key.public_key().scheme(),
508 }
509 }
510
511 pub fn public_key(&self) -> MultisigMemberPublicKey {
512 match &self.inner {
513 #[cfg(feature = "ed25519")]
514 InnerVerifyingKey::Ed25519(verifying_key) => {
515 MultisigMemberPublicKey::Ed25519(verifying_key.public_key())
516 }
517 #[cfg(feature = "secp256k1")]
518 InnerVerifyingKey::Secp256k1(verifying_key) => {
519 MultisigMemberPublicKey::Secp256k1(verifying_key.public_key())
520 }
521 #[cfg(feature = "secp256r1")]
522 InnerVerifyingKey::Secp256r1(verifying_key) => {
523 MultisigMemberPublicKey::Secp256r1(verifying_key.public_key())
524 }
525 #[cfg(feature = "mldsa65")]
526 InnerVerifyingKey::MlDsa65(verifying_key) => {
527 MultisigMemberPublicKey::MlDsa65(Box::new(verifying_key.public_key()))
528 }
529 }
530 }
531
532 pub fn derive_address(&self) -> sui_sdk_types::Address {
534 match &self.inner {
535 #[cfg(feature = "ed25519")]
536 InnerVerifyingKey::Ed25519(verifying_key) => {
537 verifying_key.public_key().derive_address()
538 }
539 #[cfg(feature = "secp256k1")]
540 InnerVerifyingKey::Secp256k1(verifying_key) => {
541 verifying_key.public_key().derive_address()
542 }
543 #[cfg(feature = "secp256r1")]
544 InnerVerifyingKey::Secp256r1(verifying_key) => {
545 verifying_key.public_key().derive_address()
546 }
547 #[cfg(feature = "mldsa65")]
548 InnerVerifyingKey::MlDsa65(verifying_key) => {
549 verifying_key.public_key().derive_address()
550 }
551 }
552 }
553
554 #[cfg(feature = "pem")]
555 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
556 pub fn from_der(bytes: &[u8]) -> Result<Self, SignatureError> {
558 let public_key = pkcs8::SubjectPublicKeyInfoRef::try_from(bytes)
559 .map_err(SignatureError::from_source)?;
560
561 match public_key
562 .algorithm
563 .oids()
564 .map_err(SignatureError::from_source)?
565 {
566 #[cfg(feature = "ed25519")]
567 (ed25519_dalek::pkcs8::ALGORITHM_OID, None) => public_key
568 .try_into()
569 .map(crate::ed25519::Ed25519VerifyingKey::from_dalek)
570 .map(InnerVerifyingKey::Ed25519)
571 .map_err(SignatureError::from_source),
572
573 #[cfg(feature = "secp256r1")]
574 (
575 p256::elliptic_curve::ALGORITHM_OID,
576 Some(<p256::NistP256 as pkcs8::AssociatedOid>::OID),
577 ) => public_key
578 .try_into()
579 .map(crate::secp256r1::Secp256r1VerifyingKey::from_p256)
580 .map(InnerVerifyingKey::Secp256r1)
581 .map_err(SignatureError::from_source),
582
583 #[cfg(feature = "secp256k1")]
584 (
585 k256::elliptic_curve::ALGORITHM_OID,
586 Some(<k256::Secp256k1 as pkcs8::AssociatedOid>::OID),
587 ) => public_key
588 .try_into()
589 .map(crate::secp256k1::Secp256k1VerifyingKey::from_k256)
590 .map(InnerVerifyingKey::Secp256k1)
591 .map_err(SignatureError::from_source),
592
593 _ => Err(SignatureError::from_source(
594 "unsupported or invalid public key type",
595 )),
596 }
597 .map(|inner| Self { inner })
598 }
599
600 #[cfg(feature = "pem")]
601 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
602 pub fn to_der(&self) -> Result<Vec<u8>, SignatureError> {
604 match &self.inner {
605 #[cfg(feature = "ed25519")]
606 InnerVerifyingKey::Ed25519(verifying_key) => verifying_key.to_der(),
607 #[cfg(feature = "secp256k1")]
608 InnerVerifyingKey::Secp256k1(verifying_key) => verifying_key.to_der(),
609 #[cfg(feature = "secp256r1")]
610 InnerVerifyingKey::Secp256r1(verifying_key) => verifying_key.to_der(),
611 #[cfg(feature = "mldsa65")]
612 InnerVerifyingKey::MlDsa65(_) => Err(SignatureError::from_source(
613 "pem encoding is not supported for mldsa65",
614 )),
615 }
616 }
617
618 #[cfg(feature = "pem")]
619 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
620 pub fn from_pem(s: &str) -> Result<Self, SignatureError> {
622 use pkcs8::der::pem::PemLabel;
623
624 let (label, doc) = pkcs8::Document::from_pem(s).map_err(SignatureError::from_source)?;
625 pkcs8::SubjectPublicKeyInfoRef::validate_pem_label(label)
626 .map_err(SignatureError::from_source)?;
627 Self::from_der(doc.as_bytes())
628 }
629
630 #[cfg(feature = "pem")]
631 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
632 pub fn to_pem(&self) -> Result<String, SignatureError> {
634 match &self.inner {
635 #[cfg(feature = "ed25519")]
636 InnerVerifyingKey::Ed25519(verifying_key) => verifying_key.to_pem(),
637 #[cfg(feature = "secp256k1")]
638 InnerVerifyingKey::Secp256k1(verifying_key) => verifying_key.to_pem(),
639 #[cfg(feature = "secp256r1")]
640 InnerVerifyingKey::Secp256r1(verifying_key) => verifying_key.to_pem(),
641 #[cfg(feature = "mldsa65")]
642 InnerVerifyingKey::MlDsa65(_) => Err(SignatureError::from_source(
643 "pem encoding is not supported for mldsa65",
644 )),
645 }
646 }
647 }
648
649 impl Verifier<SimpleSignature> for SimpleVerifiyingKey {
650 fn verify(
651 &self,
652 message: &[u8],
653 signature: &SimpleSignature,
654 ) -> Result<(), SignatureError> {
655 match &self.inner {
656 #[cfg(feature = "ed25519")]
657 InnerVerifyingKey::Ed25519(verifying_key) => {
658 verifying_key.verify(message, signature)
659 }
660 #[cfg(feature = "secp256k1")]
661 InnerVerifyingKey::Secp256k1(verifying_key) => {
662 verifying_key.verify(message, signature)
663 }
664 #[cfg(feature = "secp256r1")]
665 InnerVerifyingKey::Secp256r1(verifying_key) => {
666 verifying_key.verify(message, signature)
667 }
668 #[cfg(feature = "mldsa65")]
669 InnerVerifyingKey::MlDsa65(verifying_key) => {
670 verifying_key.verify(message, signature)
671 }
672 }
673 }
674 }
675
676 impl Verifier<UserSignature> for SimpleVerifiyingKey {
677 fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
678 let UserSignature::Simple(signature) = signature else {
679 return Err(SignatureError::from_source("not a simple signature"));
680 };
681
682 <Self as Verifier<SimpleSignature>>::verify(self, message, signature)
683 }
684 }
685
686 #[cfg(feature = "ed25519")]
687 #[cfg_attr(doc_cfg, doc(cfg(feature = "ed25519")))]
688 impl From<crate::ed25519::Ed25519VerifyingKey> for SimpleVerifiyingKey {
689 fn from(verifying_key: crate::ed25519::Ed25519VerifyingKey) -> Self {
690 Self {
691 inner: InnerVerifyingKey::Ed25519(verifying_key),
692 }
693 }
694 }
695
696 #[cfg(feature = "secp256r1")]
697 #[cfg_attr(doc_cfg, doc(cfg(feature = "secp256r1")))]
698 impl From<crate::secp256r1::Secp256r1VerifyingKey> for SimpleVerifiyingKey {
699 fn from(verifying_key: crate::secp256r1::Secp256r1VerifyingKey) -> Self {
700 Self {
701 inner: InnerVerifyingKey::Secp256r1(verifying_key),
702 }
703 }
704 }
705
706 #[cfg(feature = "secp256k1")]
707 #[cfg_attr(doc_cfg, doc(cfg(feature = "secp256k1")))]
708 impl From<crate::secp256k1::Secp256k1VerifyingKey> for SimpleVerifiyingKey {
709 fn from(verifying_key: crate::secp256k1::Secp256k1VerifyingKey) -> Self {
710 Self {
711 inner: InnerVerifyingKey::Secp256k1(verifying_key),
712 }
713 }
714 }
715
716 #[cfg(feature = "mldsa65")]
717 #[cfg_attr(doc_cfg, doc(cfg(feature = "mldsa65")))]
718 impl From<crate::mldsa65::MlDsa65VerifyingKey> for SimpleVerifiyingKey {
719 fn from(verifying_key: crate::mldsa65::MlDsa65VerifyingKey) -> Self {
720 Self {
721 inner: InnerVerifyingKey::MlDsa65(verifying_key),
722 }
723 }
724 }
725}
726
727#[cfg(test)]
728mod test {
729 use super::*;
730 use crate::ed25519::Ed25519PrivateKey;
731 use crate::ed25519::Ed25519VerifyingKey;
732 use crate::mldsa65::MlDsa65PrivateKey;
733 use crate::secp256k1::Secp256k1PrivateKey;
734 use crate::secp256k1::Secp256k1VerifyingKey;
735 use crate::secp256r1::Secp256r1PrivateKey;
736 use crate::secp256r1::Secp256r1VerifyingKey;
737 use test_strategy::proptest;
738
739 #[cfg(target_arch = "wasm32")]
740 use wasm_bindgen_test::wasm_bindgen_test as test;
741
742 #[proptest]
743 fn ed25519_pem_der(signer: Ed25519PrivateKey) {
744 let public_key = signer.public_key();
748 let ed25519_der = signer.to_der().unwrap();
749 let ed25519_pem = signer.to_pem().unwrap();
750
751 let from_der = Ed25519PrivateKey::from_der(&ed25519_der).unwrap();
753 assert_eq!(from_der.public_key(), public_key);
754 let from_pem = Ed25519PrivateKey::from_pem(&ed25519_pem).unwrap();
755 assert_eq!(from_pem.public_key(), public_key);
756
757 Secp256r1PrivateKey::from_der(&ed25519_der).unwrap_err();
759 Secp256r1PrivateKey::from_pem(&ed25519_pem).unwrap_err();
760 Secp256k1PrivateKey::from_der(&ed25519_der).unwrap_err();
761 Secp256k1PrivateKey::from_pem(&ed25519_pem).unwrap_err();
762
763 let keypair_from_der = SimpleKeypair::from_der(&ed25519_der).unwrap();
765 assert_eq!(ed25519_der, keypair_from_der.to_der().unwrap());
766 let keypair_from_pem = SimpleKeypair::from_pem(&ed25519_pem).unwrap();
767 assert_eq!(ed25519_pem, keypair_from_pem.to_pem().unwrap());
768
769 let verifying_key = signer.verifying_key();
773 let der = verifying_key.to_der().unwrap();
774 let pem = verifying_key.to_pem().unwrap();
775
776 let from_der = Ed25519VerifyingKey::from_der(&der).unwrap();
778 assert_eq!(from_der.public_key(), public_key);
779 let from_pem = Ed25519VerifyingKey::from_pem(&pem).unwrap();
780 assert_eq!(from_pem.public_key(), public_key);
781
782 Secp256r1VerifyingKey::from_der(&der).unwrap_err();
784 Secp256r1VerifyingKey::from_pem(&pem).unwrap_err();
785 Secp256k1VerifyingKey::from_der(&der).unwrap_err();
786 Secp256k1VerifyingKey::from_pem(&pem).unwrap_err();
787
788 let from_der = SimpleVerifiyingKey::from_der(&der).unwrap();
790 assert_eq!(der, from_der.to_der().unwrap());
791 let from_pem = SimpleVerifiyingKey::from_pem(&pem).unwrap();
792 assert_eq!(pem, from_pem.to_pem().unwrap());
793 }
794
795 #[proptest]
796 fn secp256r1_pem_der(signer: Secp256r1PrivateKey) {
797 let public_key = signer.public_key();
801 let secp256r1_der = signer.to_der().unwrap();
802 let secp256r1_pem = signer.to_pem().unwrap();
803
804 let from_der = Secp256r1PrivateKey::from_der(&secp256r1_der).unwrap();
806 assert_eq!(from_der.public_key(), public_key);
807 let from_pem = Secp256r1PrivateKey::from_pem(&secp256r1_pem).unwrap();
808 assert_eq!(from_pem.public_key(), public_key);
809
810 Ed25519PrivateKey::from_der(&secp256r1_der).unwrap_err();
812 Ed25519PrivateKey::from_pem(&secp256r1_pem).unwrap_err();
813 Secp256k1PrivateKey::from_der(&secp256r1_der).unwrap_err();
814 Secp256k1PrivateKey::from_pem(&secp256r1_pem).unwrap_err();
815
816 let keypair_from_der = SimpleKeypair::from_der(&secp256r1_der).unwrap();
818 assert_eq!(secp256r1_der, keypair_from_der.to_der().unwrap());
819 let keypair_from_pem = SimpleKeypair::from_pem(&secp256r1_pem).unwrap();
820 assert_eq!(secp256r1_pem, keypair_from_pem.to_pem().unwrap());
821
822 let verifying_key = signer.verifying_key();
826 let der = verifying_key.to_der().unwrap();
827 let pem = verifying_key.to_pem().unwrap();
828
829 let from_der = Secp256r1VerifyingKey::from_der(&der).unwrap();
831 assert_eq!(from_der.public_key(), public_key);
832 let from_pem = Secp256r1VerifyingKey::from_pem(&pem).unwrap();
833 assert_eq!(from_pem.public_key(), public_key);
834
835 Ed25519VerifyingKey::from_der(&der).unwrap_err();
837 Ed25519VerifyingKey::from_pem(&pem).unwrap_err();
838 Secp256k1VerifyingKey::from_der(&der).unwrap_err();
839 Secp256k1VerifyingKey::from_pem(&pem).unwrap_err();
840
841 let from_der = SimpleVerifiyingKey::from_der(&der).unwrap();
843 assert_eq!(der, from_der.to_der().unwrap());
844 let from_pem = SimpleVerifiyingKey::from_pem(&pem).unwrap();
845 assert_eq!(pem, from_pem.to_pem().unwrap());
846 }
847
848 #[proptest]
849 fn secp256k1_pem_der(signer: Secp256k1PrivateKey) {
850 let public_key = signer.public_key();
854 let secp256k1_der = signer.to_der().unwrap();
855 let secp256k1_pem = signer.to_pem().unwrap();
856
857 let from_der = Secp256k1PrivateKey::from_der(&secp256k1_der).unwrap();
859 assert_eq!(from_der.public_key(), public_key);
860 let from_pem = Secp256k1PrivateKey::from_pem(&secp256k1_pem).unwrap();
861 assert_eq!(from_pem.public_key(), public_key);
862
863 Ed25519PrivateKey::from_der(&secp256k1_der).unwrap_err();
865 Ed25519PrivateKey::from_pem(&secp256k1_pem).unwrap_err();
866 Secp256r1PrivateKey::from_der(&secp256k1_der).unwrap_err();
867 Secp256r1PrivateKey::from_pem(&secp256k1_pem).unwrap_err();
868
869 let keypair_from_der = SimpleKeypair::from_der(&secp256k1_der).unwrap();
871 assert_eq!(secp256k1_der, keypair_from_der.to_der().unwrap());
872 let keypair_from_pem = SimpleKeypair::from_pem(&secp256k1_pem).unwrap();
873 assert_eq!(secp256k1_pem, keypair_from_pem.to_pem().unwrap());
874
875 let verifying_key = signer.verifying_key();
879 let der = verifying_key.to_der().unwrap();
880 let pem = verifying_key.to_pem().unwrap();
881
882 let from_der = Secp256k1VerifyingKey::from_der(&der).unwrap();
884 assert_eq!(from_der.public_key(), public_key);
885 let from_pem = Secp256k1VerifyingKey::from_pem(&pem).unwrap();
886 assert_eq!(from_pem.public_key(), public_key);
887
888 Ed25519VerifyingKey::from_der(&der).unwrap_err();
890 Ed25519VerifyingKey::from_pem(&pem).unwrap_err();
891 Secp256r1VerifyingKey::from_der(&der).unwrap_err();
892 Secp256r1VerifyingKey::from_pem(&pem).unwrap_err();
893
894 let from_der = SimpleVerifiyingKey::from_der(&der).unwrap();
896 assert_eq!(der, from_der.to_der().unwrap());
897 let from_pem = SimpleVerifiyingKey::from_pem(&pem).unwrap();
898 assert_eq!(pem, from_pem.to_pem().unwrap());
899 }
900
901 #[test]
902 fn mldsa65_pem_der_unsupported() {
903 let keypair = SimpleKeypair::from(MlDsa65PrivateKey::new([2; 32]));
904 keypair.to_der().unwrap_err();
905 keypair.to_pem().unwrap_err();
906
907 let verifying_key = keypair.verifying_key();
908 verifying_key.to_der().unwrap_err();
909 verifying_key.to_pem().unwrap_err();
910 }
911
912 #[proptest]
913 fn mldsa65_sign_and_verify(signer: MlDsa65PrivateKey, message: Vec<u8>, seed: u64) {
914 use crate::test_util::TestRng;
915 use signature::RandomizedSigner;
916 use signature::Signer;
917
918 let keypair = SimpleKeypair::from(signer.clone());
919 assert_eq!(keypair.scheme(), sui_sdk_types::SignatureScheme::MlDsa65);
920 assert_eq!(
921 keypair.verifying_key(),
922 SimpleVerifiyingKey::from(signer.verifying_key())
923 );
924
925 Signer::<SimpleSignature>::try_sign(&keypair, &message).unwrap_err();
928 Signer::<UserSignature>::try_sign(&keypair, &message).unwrap_err();
929
930 let signature: UserSignature = keypair
931 .try_sign_with_rng(&mut TestRng(seed), &message)
932 .unwrap();
933 keypair
934 .verifying_key()
935 .verify(&message, &signature)
936 .unwrap();
937 SimpleVerifier.verify(&message, &signature).unwrap();
938
939 let mut other_message = message.clone();
941 other_message.push(0);
942 keypair
943 .verifying_key()
944 .verify(&other_message, &signature)
945 .unwrap_err();
946 let mut other_seed = *signer.seed();
947 other_seed[0] ^= 1;
948 SimpleKeypair::from(MlDsa65PrivateKey::new(other_seed))
949 .verifying_key()
950 .verify(&message, &signature)
951 .unwrap_err();
952 }
953
954 #[proptest]
958 fn randomized_signer_matches_signer_for_deterministic_schemes(
959 ed25519: Ed25519PrivateKey,
960 secp256k1: Secp256k1PrivateKey,
961 secp256r1: Secp256r1PrivateKey,
962 message: Vec<u8>,
963 seed: u64,
964 ) {
965 use crate::test_util::TestRng;
966 use signature::RandomizedSigner;
967 use signature::Signer;
968
969 for keypair in [
970 SimpleKeypair::from(ed25519),
971 SimpleKeypair::from(secp256k1),
972 SimpleKeypair::from(secp256r1),
973 ] {
974 let expected: UserSignature = keypair.try_sign(&message).unwrap();
975 let signature: UserSignature = keypair
976 .try_sign_with_rng(&mut TestRng(seed), &message)
977 .unwrap();
978 assert_eq!(signature, expected);
979 }
980 }
981
982 #[proptest]
983 fn simple_verifying_key_derives_matching_address(
984 ed25519: Ed25519PrivateKey,
985 secp256k1: Secp256k1PrivateKey,
986 secp256r1: Secp256r1PrivateKey,
987 mldsa65: MlDsa65PrivateKey,
988 ) {
989 let expected = ed25519.public_key().derive_address();
992 let keypair = SimpleKeypair::from(ed25519);
993 assert_eq!(keypair.verifying_key().derive_address(), expected);
994
995 let expected = secp256k1.public_key().derive_address();
996 let keypair = SimpleKeypair::from(secp256k1);
997 assert_eq!(keypair.verifying_key().derive_address(), expected);
998
999 let expected = secp256r1.public_key().derive_address();
1000 let keypair = SimpleKeypair::from(secp256r1);
1001 assert_eq!(keypair.verifying_key().derive_address(), expected);
1002
1003 let expected = mldsa65.public_key().derive_address();
1004 let keypair = SimpleKeypair::from(mldsa65);
1005 assert_eq!(keypair.verifying_key().derive_address(), expected);
1006 }
1007
1008 #[cfg(feature = "bech32")]
1016 mod bech32 {
1017 use super::*;
1018 use sui_sdk_types::SignatureScheme;
1019
1020 #[cfg(target_arch = "wasm32")]
1021 use wasm_bindgen_test::wasm_bindgen_test as test;
1022
1023 const UPSTREAM_ED25519_SUIPRIVKEY: &str =
1028 "suiprivkey1qzdlfxn2qa2lj5uprl8pyhexs02sg2wrhdy7qaq50cqgnffw4c2477kg9h3";
1029
1030 #[proptest]
1031 fn ed25519_round_trip(signer: Ed25519PrivateKey) {
1032 let encoded = signer.to_suiprivkey().unwrap();
1033 let decoded = Ed25519PrivateKey::from_suiprivkey(&encoded).unwrap();
1034 assert_eq!(decoded.public_key(), signer.public_key());
1035
1036 let keypair = SimpleKeypair::from_suiprivkey(&encoded).unwrap();
1038 assert_eq!(keypair.scheme(), signer.scheme());
1039 assert_eq!(encoded, keypair.to_suiprivkey().unwrap());
1040 }
1041
1042 #[proptest]
1043 fn secp256k1_round_trip(signer: Secp256k1PrivateKey) {
1044 let encoded = signer.to_suiprivkey().unwrap();
1045 let decoded = Secp256k1PrivateKey::from_suiprivkey(&encoded).unwrap();
1046 assert_eq!(decoded.public_key(), signer.public_key());
1047
1048 let keypair = SimpleKeypair::from_suiprivkey(&encoded).unwrap();
1049 assert_eq!(keypair.scheme(), signer.scheme());
1050 assert_eq!(encoded, keypair.to_suiprivkey().unwrap());
1051 }
1052
1053 #[proptest]
1054 fn secp256r1_round_trip(signer: Secp256r1PrivateKey) {
1055 let encoded = signer.to_suiprivkey().unwrap();
1056 let decoded = Secp256r1PrivateKey::from_suiprivkey(&encoded).unwrap();
1057 assert_eq!(decoded.public_key(), signer.public_key());
1058
1059 let keypair = SimpleKeypair::from_suiprivkey(&encoded).unwrap();
1060 assert_eq!(keypair.scheme(), signer.scheme());
1061 assert_eq!(encoded, keypair.to_suiprivkey().unwrap());
1062 }
1063
1064 #[proptest]
1065 fn mldsa65_round_trip(signer: MlDsa65PrivateKey) {
1066 let encoded = signer.to_suiprivkey().unwrap();
1067 let decoded = MlDsa65PrivateKey::from_suiprivkey(&encoded).unwrap();
1068 assert_eq!(decoded.public_key(), signer.public_key());
1069
1070 let keypair = SimpleKeypair::from_suiprivkey(&encoded).unwrap();
1071 assert_eq!(keypair.scheme(), signer.scheme());
1072 assert_eq!(
1073 keypair.verifying_key(),
1074 SimpleVerifiyingKey::from(signer.verifying_key())
1075 );
1076 assert_eq!(encoded, keypair.to_suiprivkey().unwrap());
1077
1078 Ed25519PrivateKey::from_suiprivkey(&encoded).unwrap_err();
1080 Secp256k1PrivateKey::from_suiprivkey(&encoded).unwrap_err();
1081 Secp256r1PrivateKey::from_suiprivkey(&encoded).unwrap_err();
1082 }
1083
1084 #[test]
1085 fn upstream_ed25519_vector_round_trips() {
1086 let keypair = SimpleKeypair::from_suiprivkey(UPSTREAM_ED25519_SUIPRIVKEY).unwrap();
1087 assert_eq!(keypair.scheme(), SignatureScheme::Ed25519);
1088 assert_eq!(
1089 keypair.to_suiprivkey().unwrap(),
1090 UPSTREAM_ED25519_SUIPRIVKEY
1091 );
1092
1093 Ed25519PrivateKey::from_suiprivkey(UPSTREAM_ED25519_SUIPRIVKEY).unwrap();
1095 Secp256k1PrivateKey::from_suiprivkey(UPSTREAM_ED25519_SUIPRIVKEY).unwrap_err();
1097 Secp256r1PrivateKey::from_suiprivkey(UPSTREAM_ED25519_SUIPRIVKEY).unwrap_err();
1098 MlDsa65PrivateKey::from_suiprivkey(UPSTREAM_ED25519_SUIPRIVKEY).unwrap_err();
1099 }
1100
1101 #[test]
1102 fn rejects_wrong_hrp() {
1103 let bytes = ::bech32::primitives::decode::CheckedHrpstring::new::<::bech32::Bech32>(
1106 UPSTREAM_ED25519_SUIPRIVKEY,
1107 )
1108 .unwrap()
1109 .byte_iter()
1110 .collect::<Vec<_>>();
1111 let wrong_hrp = ::bech32::Hrp::parse("notsui").unwrap();
1112 let encoded = ::bech32::encode::<::bech32::Bech32>(wrong_hrp, &bytes).unwrap();
1113
1114 SimpleKeypair::from_suiprivkey(&encoded).unwrap_err();
1115 Ed25519PrivateKey::from_suiprivkey(&encoded).unwrap_err();
1116 }
1117
1118 #[test]
1119 fn rejects_bech32m_checksum() {
1120 let bytes = ::bech32::primitives::decode::CheckedHrpstring::new::<::bech32::Bech32>(
1124 UPSTREAM_ED25519_SUIPRIVKEY,
1125 )
1126 .unwrap()
1127 .byte_iter()
1128 .collect::<Vec<_>>();
1129 let hrp = ::bech32::Hrp::parse("suiprivkey").unwrap();
1130 let bech32m = ::bech32::encode::<::bech32::Bech32m>(hrp, &bytes).unwrap();
1131 assert_ne!(bech32m, UPSTREAM_ED25519_SUIPRIVKEY);
1132
1133 SimpleKeypair::from_suiprivkey(&bech32m).unwrap_err();
1134 Ed25519PrivateKey::from_suiprivkey(&bech32m).unwrap_err();
1135 }
1136 }
1137
1138 mod base64 {
1144 use super::*;
1145 use sui_sdk_types::SignatureScheme;
1146
1147 #[cfg(target_arch = "wasm32")]
1148 use wasm_bindgen_test::wasm_bindgen_test as test;
1149
1150 const UPSTREAM_ED25519_BASE64: &str = "AJv0mmoHVflTgR/OEl8mg9UEKcO7SeB0FH4AiaUurhVf";
1155
1156 #[proptest]
1157 fn ed25519_round_trip(signer: Ed25519PrivateKey) {
1158 let encoded = signer.to_base64();
1159 let decoded = Ed25519PrivateKey::from_base64(&encoded).unwrap();
1160 assert_eq!(decoded.public_key(), signer.public_key());
1161
1162 let keypair = SimpleKeypair::from_base64(&encoded).unwrap();
1164 assert_eq!(keypair.scheme(), signer.scheme());
1165 assert_eq!(encoded, keypair.to_base64());
1166 }
1167
1168 #[proptest]
1169 fn secp256k1_round_trip(signer: Secp256k1PrivateKey) {
1170 let encoded = signer.to_base64();
1171 let decoded = Secp256k1PrivateKey::from_base64(&encoded).unwrap();
1172 assert_eq!(decoded.public_key(), signer.public_key());
1173
1174 let keypair = SimpleKeypair::from_base64(&encoded).unwrap();
1175 assert_eq!(keypair.scheme(), signer.scheme());
1176 assert_eq!(encoded, keypair.to_base64());
1177 }
1178
1179 #[proptest]
1180 fn secp256r1_round_trip(signer: Secp256r1PrivateKey) {
1181 let encoded = signer.to_base64();
1182 let decoded = Secp256r1PrivateKey::from_base64(&encoded).unwrap();
1183 assert_eq!(decoded.public_key(), signer.public_key());
1184
1185 let keypair = SimpleKeypair::from_base64(&encoded).unwrap();
1186 assert_eq!(keypair.scheme(), signer.scheme());
1187 assert_eq!(encoded, keypair.to_base64());
1188 }
1189
1190 #[proptest]
1191 fn mldsa65_round_trip(signer: MlDsa65PrivateKey) {
1192 let encoded = signer.to_base64();
1193 let decoded = MlDsa65PrivateKey::from_base64(&encoded).unwrap();
1194 assert_eq!(decoded.public_key(), signer.public_key());
1195
1196 let keypair = SimpleKeypair::from_base64(&encoded).unwrap();
1197 assert_eq!(keypair.scheme(), signer.scheme());
1198 assert_eq!(
1199 keypair.verifying_key(),
1200 SimpleVerifiyingKey::from(signer.verifying_key())
1201 );
1202 assert_eq!(encoded, keypair.to_base64());
1203
1204 Ed25519PrivateKey::from_base64(&encoded).unwrap_err();
1206 Secp256k1PrivateKey::from_base64(&encoded).unwrap_err();
1207 Secp256r1PrivateKey::from_base64(&encoded).unwrap_err();
1208 }
1209
1210 #[test]
1211 fn upstream_ed25519_vector_round_trips() {
1212 let keypair = SimpleKeypair::from_base64(UPSTREAM_ED25519_BASE64).unwrap();
1213 assert_eq!(keypair.scheme(), SignatureScheme::Ed25519);
1214 assert_eq!(keypair.to_base64(), UPSTREAM_ED25519_BASE64);
1215
1216 Ed25519PrivateKey::from_base64(UPSTREAM_ED25519_BASE64).unwrap();
1218 Secp256k1PrivateKey::from_base64(UPSTREAM_ED25519_BASE64).unwrap_err();
1220 Secp256r1PrivateKey::from_base64(UPSTREAM_ED25519_BASE64).unwrap_err();
1221 MlDsa65PrivateKey::from_base64(UPSTREAM_ED25519_BASE64).unwrap_err();
1222 }
1223
1224 #[cfg(feature = "bech32")]
1225 #[test]
1226 fn agrees_with_suiprivkey_encoding() {
1227 let keypair = SimpleKeypair::from_base64(UPSTREAM_ED25519_BASE64).unwrap();
1230 let suiprivkey = keypair.to_suiprivkey().unwrap();
1231 let round_tripped = SimpleKeypair::from_suiprivkey(&suiprivkey).unwrap();
1232 assert_eq!(round_tripped.to_base64(), UPSTREAM_ED25519_BASE64);
1233 }
1234
1235 #[test]
1236 fn rejects_invalid_input() {
1237 SimpleKeypair::from_base64("not base64!").unwrap_err();
1239 Ed25519PrivateKey::from_base64("not base64!").unwrap_err();
1240
1241 SimpleKeypair::from_base64("").unwrap_err();
1243
1244 use base64ct::Encoding;
1246 let payload = base64ct::Base64::decode_vec(UPSTREAM_ED25519_BASE64).unwrap();
1247 let mut bad_flag_payload = payload.clone();
1248 bad_flag_payload[0] = 0xff;
1249 let bad_flag = base64ct::Base64::encode_string(&bad_flag_payload);
1250 SimpleKeypair::from_base64(&bad_flag).unwrap_err();
1251
1252 let truncated = base64ct::Base64::encode_string(&payload[..16]);
1254 SimpleKeypair::from_base64(&truncated).unwrap_err();
1255
1256 let mut short_seed = vec![SignatureScheme::MlDsa65.to_u8()];
1258 short_seed.extend_from_slice(&[0; MlDsa65PrivateKey::LENGTH - 1]);
1259 let short_seed = base64ct::Base64::encode_string(&short_seed);
1260 SimpleKeypair::from_base64(&short_seed).unwrap_err();
1261 MlDsa65PrivateKey::from_base64(&short_seed).unwrap_err();
1262 }
1263
1264 #[test]
1265 fn rejects_invalid_ecdsa_scalar() {
1266 use base64ct::Encoding;
1270 for scheme in [SignatureScheme::Secp256k1, SignatureScheme::Secp256r1] {
1271 let mut payload = vec![scheme.to_u8()];
1272 payload.extend_from_slice(&[0; 32]);
1273 let encoded = base64ct::Base64::encode_string(&payload);
1274
1275 SimpleKeypair::from_base64(&encoded).unwrap_err();
1276 }
1277 }
1278 }
1279}