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 _ => Err(SignatureError::from_source("unknown signature scheme")),
49 }
50 }
51}
52
53impl Verifier<UserSignature> for SimpleVerifier {
54 fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
55 let UserSignature::Simple(signature) = signature else {
56 return Err(SignatureError::from_source("not a simple signature"));
57 };
58
59 <Self as Verifier<SimpleSignature>>::verify(self, message, signature)
60 }
61}
62
63#[cfg(any(feature = "ed25519", feature = "secp256r1", feature = "secp256k1",))]
64#[cfg_attr(
65 doc_cfg,
66 doc(cfg(any(feature = "ed25519", feature = "secp256r1", feature = "secp256k1",)))
67)]
68#[rustfmt::skip]
69pub use keypair::{SimpleKeypair, SimpleVerifiyingKey};
70
71#[cfg(any(feature = "ed25519", feature = "secp256r1", feature = "secp256k1",))]
72#[cfg_attr(
73 doc_cfg,
74 doc(cfg(any(feature = "ed25519", feature = "secp256r1", feature = "secp256k1",)))
75)]
76mod keypair {
77 use crate::SignatureError;
78 use signature::Signer;
79 use signature::Verifier;
80 use sui_sdk_types::MultisigMemberPublicKey;
81 use sui_sdk_types::SignatureScheme;
82 use sui_sdk_types::SimpleSignature;
83 use sui_sdk_types::UserSignature;
84
85 #[derive(Debug, Clone)]
86 pub struct SimpleKeypair {
87 inner: InnerKeypair,
88 }
89
90 #[derive(Debug, Clone)]
91 enum InnerKeypair {
92 #[cfg(feature = "ed25519")]
93 Ed25519(crate::ed25519::Ed25519PrivateKey),
94 #[cfg(feature = "secp256k1")]
95 Secp256k1(crate::secp256k1::Secp256k1PrivateKey),
96 #[cfg(feature = "secp256r1")]
97 Secp256r1(crate::secp256r1::Secp256r1PrivateKey),
98 }
99
100 impl SimpleKeypair {
101 pub fn scheme(&self) -> SignatureScheme {
102 match &self.inner {
103 #[cfg(feature = "ed25519")]
104 InnerKeypair::Ed25519(private_key) => private_key.scheme(),
105 #[cfg(feature = "secp256k1")]
106 InnerKeypair::Secp256k1(private_key) => private_key.scheme(),
107 #[cfg(feature = "secp256r1")]
108 InnerKeypair::Secp256r1(private_key) => private_key.scheme(),
109 }
110 }
111
112 pub fn verifying_key(&self) -> SimpleVerifiyingKey {
113 let verifying_key = match &self.inner {
114 #[cfg(feature = "ed25519")]
115 InnerKeypair::Ed25519(private_key) => {
116 InnerVerifyingKey::Ed25519(private_key.verifying_key())
117 }
118 #[cfg(feature = "secp256k1")]
119 InnerKeypair::Secp256k1(private_key) => {
120 InnerVerifyingKey::Secp256k1(private_key.verifying_key())
121 }
122 #[cfg(feature = "secp256r1")]
123 InnerKeypair::Secp256r1(private_key) => {
124 InnerVerifyingKey::Secp256r1(private_key.verifying_key())
125 }
126 };
127
128 SimpleVerifiyingKey {
129 inner: verifying_key,
130 }
131 }
132
133 pub fn public_key(&self) -> MultisigMemberPublicKey {
134 self.verifying_key().public_key()
135 }
136
137 #[cfg(feature = "pem")]
138 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
139 pub fn from_der(bytes: &[u8]) -> Result<Self, SignatureError> {
141 let private_key =
142 pkcs8::PrivateKeyInfo::try_from(bytes).map_err(SignatureError::from_source)?;
143
144 match private_key
145 .algorithm
146 .oids()
147 .map_err(SignatureError::from_source)?
148 {
149 #[cfg(feature = "ed25519")]
150 (ed25519_dalek::pkcs8::ALGORITHM_OID, None) => private_key
151 .try_into()
152 .map(crate::ed25519::Ed25519PrivateKey::from_dalek)
153 .map(InnerKeypair::Ed25519)
154 .map_err(SignatureError::from_source),
155
156 #[cfg(feature = "secp256r1")]
157 (
158 p256::elliptic_curve::ALGORITHM_OID,
159 Some(<p256::NistP256 as pkcs8::AssociatedOid>::OID),
160 ) => private_key
161 .try_into()
162 .map(crate::secp256r1::Secp256r1PrivateKey::from_p256)
163 .map(InnerKeypair::Secp256r1)
164 .map_err(SignatureError::from_source),
165
166 #[cfg(feature = "secp256k1")]
167 (
168 k256::elliptic_curve::ALGORITHM_OID,
169 Some(<k256::Secp256k1 as pkcs8::AssociatedOid>::OID),
170 ) => private_key
171 .try_into()
172 .map(crate::secp256k1::Secp256k1PrivateKey::from_k256)
173 .map(InnerKeypair::Secp256k1)
174 .map_err(SignatureError::from_source),
175
176 _ => Err(SignatureError::from_source(
177 "unsupported or invalid private key type",
178 )),
179 }
180 .map(|inner| Self { inner })
181 }
182
183 #[cfg(feature = "pem")]
184 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
185 pub fn to_der(&self) -> Result<Vec<u8>, SignatureError> {
187 match &self.inner {
188 #[cfg(feature = "ed25519")]
189 InnerKeypair::Ed25519(private_key) => private_key.to_der(),
190 #[cfg(feature = "secp256k1")]
191 InnerKeypair::Secp256k1(private_key) => private_key.to_der(),
192 #[cfg(feature = "secp256r1")]
193 InnerKeypair::Secp256r1(private_key) => private_key.to_der(),
194 }
195 }
196
197 #[cfg(feature = "pem")]
198 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
199 pub fn from_pem(s: &str) -> Result<Self, SignatureError> {
201 use pkcs8::der::pem::PemLabel;
202
203 let (label, doc) =
204 pkcs8::SecretDocument::from_pem(s).map_err(SignatureError::from_source)?;
205 pkcs8::PrivateKeyInfo::validate_pem_label(label)
206 .map_err(SignatureError::from_source)?;
207 Self::from_der(doc.as_bytes())
208 }
209
210 #[cfg(feature = "pem")]
211 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
212 pub fn to_pem(&self) -> Result<String, SignatureError> {
214 match &self.inner {
215 #[cfg(feature = "ed25519")]
216 InnerKeypair::Ed25519(private_key) => private_key.to_pem(),
217 #[cfg(feature = "secp256k1")]
218 InnerKeypair::Secp256k1(private_key) => private_key.to_pem(),
219 #[cfg(feature = "secp256r1")]
220 InnerKeypair::Secp256r1(private_key) => private_key.to_pem(),
221 }
222 }
223
224 fn from_flagged_key_bytes(
230 scheme: SignatureScheme,
231 key: Vec<u8>,
232 ) -> Result<Self, SignatureError> {
233 let inner = match scheme {
234 #[cfg(feature = "ed25519")]
235 SignatureScheme::Ed25519 => {
236 let bytes: [u8; crate::ed25519::Ed25519PrivateKey::LENGTH] =
237 key.try_into().map_err(|_: Vec<u8>| {
238 SignatureError::from_source(
239 "private key has invalid length for ed25519",
240 )
241 })?;
242 InnerKeypair::Ed25519(crate::ed25519::Ed25519PrivateKey::new(bytes))
243 }
244 #[cfg(feature = "secp256k1")]
245 SignatureScheme::Secp256k1 => {
246 let bytes: [u8; crate::secp256k1::Secp256k1PrivateKey::LENGTH] =
247 key.try_into().map_err(|_: Vec<u8>| {
248 SignatureError::from_source(
249 "private key has invalid length for secp256k1",
250 )
251 })?;
252 InnerKeypair::Secp256k1(crate::secp256k1::Secp256k1PrivateKey::new(bytes)?)
253 }
254 #[cfg(feature = "secp256r1")]
255 SignatureScheme::Secp256r1 => {
256 let bytes: [u8; crate::secp256r1::Secp256r1PrivateKey::LENGTH] =
257 key.try_into().map_err(|_: Vec<u8>| {
258 SignatureError::from_source(
259 "private key has invalid length for secp256r1",
260 )
261 })?;
262 InnerKeypair::Secp256r1(crate::secp256r1::Secp256r1PrivateKey::new(bytes))
263 }
264 other => {
265 return Err(SignatureError::from_source(format!(
266 "unsupported scheme `{}` in private key encoding",
267 other.name(),
268 )));
269 }
270 };
271 Ok(Self { inner })
272 }
273
274 #[cfg(feature = "bech32")]
275 #[cfg_attr(doc_cfg, doc(cfg(feature = "bech32")))]
276 pub fn from_suiprivkey(s: &str) -> Result<Self, SignatureError> {
282 let (scheme, key) = crate::suipriv::decode(s)?;
283 Self::from_flagged_key_bytes(scheme, key)
284 }
285
286 #[cfg(feature = "bech32")]
287 #[cfg_attr(doc_cfg, doc(cfg(feature = "bech32")))]
288 pub fn to_suiprivkey(&self) -> Result<String, SignatureError> {
290 match &self.inner {
291 #[cfg(feature = "ed25519")]
292 InnerKeypair::Ed25519(private_key) => private_key.to_suiprivkey(),
293 #[cfg(feature = "secp256k1")]
294 InnerKeypair::Secp256k1(private_key) => private_key.to_suiprivkey(),
295 #[cfg(feature = "secp256r1")]
296 InnerKeypair::Secp256r1(private_key) => private_key.to_suiprivkey(),
297 }
298 }
299
300 pub fn from_base64(s: &str) -> Result<Self, SignatureError> {
307 let (scheme, key) = crate::suipriv::decode_base64(s)?;
308 Self::from_flagged_key_bytes(scheme, key)
309 }
310
311 pub fn to_base64(&self) -> String {
315 match &self.inner {
316 #[cfg(feature = "ed25519")]
317 InnerKeypair::Ed25519(private_key) => private_key.to_base64(),
318 #[cfg(feature = "secp256k1")]
319 InnerKeypair::Secp256k1(private_key) => private_key.to_base64(),
320 #[cfg(feature = "secp256r1")]
321 InnerKeypair::Secp256r1(private_key) => private_key.to_base64(),
322 }
323 }
324 }
325
326 impl Signer<SimpleSignature> for SimpleKeypair {
327 fn try_sign(&self, message: &[u8]) -> Result<SimpleSignature, SignatureError> {
328 match &self.inner {
329 #[cfg(feature = "ed25519")]
330 InnerKeypair::Ed25519(private_key) => private_key.try_sign(message),
331 #[cfg(feature = "secp256k1")]
332 InnerKeypair::Secp256k1(private_key) => private_key.try_sign(message),
333 #[cfg(feature = "secp256r1")]
334 InnerKeypair::Secp256r1(private_key) => private_key.try_sign(message),
335 }
336 }
337 }
338
339 impl Signer<UserSignature> for SimpleKeypair {
340 fn try_sign(&self, msg: &[u8]) -> Result<UserSignature, SignatureError> {
341 <Self as Signer<SimpleSignature>>::try_sign(self, msg).map(UserSignature::Simple)
342 }
343 }
344
345 #[cfg(feature = "ed25519")]
346 #[cfg_attr(doc_cfg, doc(cfg(feature = "ed25519")))]
347 impl From<crate::ed25519::Ed25519PrivateKey> for SimpleKeypair {
348 fn from(private_key: crate::ed25519::Ed25519PrivateKey) -> Self {
349 Self {
350 inner: InnerKeypair::Ed25519(private_key),
351 }
352 }
353 }
354
355 #[cfg(feature = "secp256r1")]
356 #[cfg_attr(doc_cfg, doc(cfg(feature = "secp256r1")))]
357 impl From<crate::secp256r1::Secp256r1PrivateKey> for SimpleKeypair {
358 fn from(private_key: crate::secp256r1::Secp256r1PrivateKey) -> Self {
359 Self {
360 inner: InnerKeypair::Secp256r1(private_key),
361 }
362 }
363 }
364
365 #[cfg(feature = "secp256k1")]
366 #[cfg_attr(doc_cfg, doc(cfg(feature = "secp256k1")))]
367 impl From<crate::secp256k1::Secp256k1PrivateKey> for SimpleKeypair {
368 fn from(private_key: crate::secp256k1::Secp256k1PrivateKey) -> Self {
369 Self {
370 inner: InnerKeypair::Secp256k1(private_key),
371 }
372 }
373 }
374
375 #[derive(Debug, Clone, Eq, PartialEq)]
376 pub struct SimpleVerifiyingKey {
377 inner: InnerVerifyingKey,
378 }
379
380 #[derive(Debug, Clone, Eq, PartialEq)]
381 enum InnerVerifyingKey {
382 #[cfg(feature = "ed25519")]
383 Ed25519(crate::ed25519::Ed25519VerifyingKey),
384 #[cfg(feature = "secp256k1")]
385 Secp256k1(crate::secp256k1::Secp256k1VerifyingKey),
386 #[cfg(feature = "secp256r1")]
387 Secp256r1(crate::secp256r1::Secp256r1VerifyingKey),
388 }
389
390 impl SimpleVerifiyingKey {
391 pub fn scheme(&self) -> SignatureScheme {
392 match &self.inner {
393 #[cfg(feature = "ed25519")]
394 InnerVerifyingKey::Ed25519(verifying_key) => verifying_key.public_key().scheme(),
395 #[cfg(feature = "secp256k1")]
396 InnerVerifyingKey::Secp256k1(verifying_key) => verifying_key.public_key().scheme(),
397 #[cfg(feature = "secp256r1")]
398 InnerVerifyingKey::Secp256r1(verifying_key) => verifying_key.public_key().scheme(),
399 }
400 }
401
402 pub fn public_key(&self) -> MultisigMemberPublicKey {
403 match &self.inner {
404 #[cfg(feature = "ed25519")]
405 InnerVerifyingKey::Ed25519(verifying_key) => {
406 MultisigMemberPublicKey::Ed25519(verifying_key.public_key())
407 }
408 #[cfg(feature = "secp256k1")]
409 InnerVerifyingKey::Secp256k1(verifying_key) => {
410 MultisigMemberPublicKey::Secp256k1(verifying_key.public_key())
411 }
412 #[cfg(feature = "secp256r1")]
413 InnerVerifyingKey::Secp256r1(verifying_key) => {
414 MultisigMemberPublicKey::Secp256r1(verifying_key.public_key())
415 }
416 }
417 }
418
419 pub fn derive_address(&self) -> sui_sdk_types::Address {
421 match &self.inner {
422 #[cfg(feature = "ed25519")]
423 InnerVerifyingKey::Ed25519(verifying_key) => {
424 verifying_key.public_key().derive_address()
425 }
426 #[cfg(feature = "secp256k1")]
427 InnerVerifyingKey::Secp256k1(verifying_key) => {
428 verifying_key.public_key().derive_address()
429 }
430 #[cfg(feature = "secp256r1")]
431 InnerVerifyingKey::Secp256r1(verifying_key) => {
432 verifying_key.public_key().derive_address()
433 }
434 }
435 }
436
437 #[cfg(feature = "pem")]
438 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
439 pub fn from_der(bytes: &[u8]) -> Result<Self, SignatureError> {
441 let public_key = pkcs8::SubjectPublicKeyInfoRef::try_from(bytes)
442 .map_err(SignatureError::from_source)?;
443
444 match public_key
445 .algorithm
446 .oids()
447 .map_err(SignatureError::from_source)?
448 {
449 #[cfg(feature = "ed25519")]
450 (ed25519_dalek::pkcs8::ALGORITHM_OID, None) => public_key
451 .try_into()
452 .map(crate::ed25519::Ed25519VerifyingKey::from_dalek)
453 .map(InnerVerifyingKey::Ed25519)
454 .map_err(SignatureError::from_source),
455
456 #[cfg(feature = "secp256r1")]
457 (
458 p256::elliptic_curve::ALGORITHM_OID,
459 Some(<p256::NistP256 as pkcs8::AssociatedOid>::OID),
460 ) => public_key
461 .try_into()
462 .map(crate::secp256r1::Secp256r1VerifyingKey::from_p256)
463 .map(InnerVerifyingKey::Secp256r1)
464 .map_err(SignatureError::from_source),
465
466 #[cfg(feature = "secp256k1")]
467 (
468 k256::elliptic_curve::ALGORITHM_OID,
469 Some(<k256::Secp256k1 as pkcs8::AssociatedOid>::OID),
470 ) => public_key
471 .try_into()
472 .map(crate::secp256k1::Secp256k1VerifyingKey::from_k256)
473 .map(InnerVerifyingKey::Secp256k1)
474 .map_err(SignatureError::from_source),
475
476 _ => Err(SignatureError::from_source(
477 "unsupported or invalid public key type",
478 )),
479 }
480 .map(|inner| Self { inner })
481 }
482
483 #[cfg(feature = "pem")]
484 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
485 pub fn to_der(&self) -> Result<Vec<u8>, SignatureError> {
487 match &self.inner {
488 #[cfg(feature = "ed25519")]
489 InnerVerifyingKey::Ed25519(verifying_key) => verifying_key.to_der(),
490 #[cfg(feature = "secp256k1")]
491 InnerVerifyingKey::Secp256k1(verifying_key) => verifying_key.to_der(),
492 #[cfg(feature = "secp256r1")]
493 InnerVerifyingKey::Secp256r1(verifying_key) => verifying_key.to_der(),
494 }
495 }
496
497 #[cfg(feature = "pem")]
498 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
499 pub fn from_pem(s: &str) -> Result<Self, SignatureError> {
501 use pkcs8::der::pem::PemLabel;
502
503 let (label, doc) = pkcs8::Document::from_pem(s).map_err(SignatureError::from_source)?;
504 pkcs8::SubjectPublicKeyInfoRef::validate_pem_label(label)
505 .map_err(SignatureError::from_source)?;
506 Self::from_der(doc.as_bytes())
507 }
508
509 #[cfg(feature = "pem")]
510 #[cfg_attr(doc_cfg, doc(cfg(feature = "pem")))]
511 pub fn to_pem(&self) -> Result<String, SignatureError> {
513 match &self.inner {
514 #[cfg(feature = "ed25519")]
515 InnerVerifyingKey::Ed25519(verifying_key) => verifying_key.to_pem(),
516 #[cfg(feature = "secp256k1")]
517 InnerVerifyingKey::Secp256k1(verifying_key) => verifying_key.to_pem(),
518 #[cfg(feature = "secp256r1")]
519 InnerVerifyingKey::Secp256r1(verifying_key) => verifying_key.to_pem(),
520 }
521 }
522 }
523
524 impl Verifier<SimpleSignature> for SimpleVerifiyingKey {
525 fn verify(
526 &self,
527 message: &[u8],
528 signature: &SimpleSignature,
529 ) -> Result<(), SignatureError> {
530 match &self.inner {
531 #[cfg(feature = "ed25519")]
532 InnerVerifyingKey::Ed25519(verifying_key) => {
533 verifying_key.verify(message, signature)
534 }
535 #[cfg(feature = "secp256k1")]
536 InnerVerifyingKey::Secp256k1(verifying_key) => {
537 verifying_key.verify(message, signature)
538 }
539 #[cfg(feature = "secp256r1")]
540 InnerVerifyingKey::Secp256r1(verifying_key) => {
541 verifying_key.verify(message, signature)
542 }
543 }
544 }
545 }
546
547 impl Verifier<UserSignature> for SimpleVerifiyingKey {
548 fn verify(&self, message: &[u8], signature: &UserSignature) -> Result<(), SignatureError> {
549 let UserSignature::Simple(signature) = signature else {
550 return Err(SignatureError::from_source("not a simple signature"));
551 };
552
553 <Self as Verifier<SimpleSignature>>::verify(self, message, signature)
554 }
555 }
556
557 #[cfg(feature = "ed25519")]
558 #[cfg_attr(doc_cfg, doc(cfg(feature = "ed25519")))]
559 impl From<crate::ed25519::Ed25519VerifyingKey> for SimpleVerifiyingKey {
560 fn from(verifying_key: crate::ed25519::Ed25519VerifyingKey) -> Self {
561 Self {
562 inner: InnerVerifyingKey::Ed25519(verifying_key),
563 }
564 }
565 }
566
567 #[cfg(feature = "secp256r1")]
568 #[cfg_attr(doc_cfg, doc(cfg(feature = "secp256r1")))]
569 impl From<crate::secp256r1::Secp256r1VerifyingKey> for SimpleVerifiyingKey {
570 fn from(verifying_key: crate::secp256r1::Secp256r1VerifyingKey) -> Self {
571 Self {
572 inner: InnerVerifyingKey::Secp256r1(verifying_key),
573 }
574 }
575 }
576
577 #[cfg(feature = "secp256k1")]
578 #[cfg_attr(doc_cfg, doc(cfg(feature = "secp256k1")))]
579 impl From<crate::secp256k1::Secp256k1VerifyingKey> for SimpleVerifiyingKey {
580 fn from(verifying_key: crate::secp256k1::Secp256k1VerifyingKey) -> Self {
581 Self {
582 inner: InnerVerifyingKey::Secp256k1(verifying_key),
583 }
584 }
585 }
586}
587
588#[cfg(test)]
589mod test {
590 use super::*;
591 use crate::ed25519::Ed25519PrivateKey;
592 use crate::ed25519::Ed25519VerifyingKey;
593 use crate::secp256k1::Secp256k1PrivateKey;
594 use crate::secp256k1::Secp256k1VerifyingKey;
595 use crate::secp256r1::Secp256r1PrivateKey;
596 use crate::secp256r1::Secp256r1VerifyingKey;
597 use test_strategy::proptest;
598
599 #[cfg(target_arch = "wasm32")]
600 use wasm_bindgen_test::wasm_bindgen_test as test;
601
602 #[proptest]
603 fn ed25519_pem_der(signer: Ed25519PrivateKey) {
604 let public_key = signer.public_key();
608 let ed25519_der = signer.to_der().unwrap();
609 let ed25519_pem = signer.to_pem().unwrap();
610
611 let from_der = Ed25519PrivateKey::from_der(&ed25519_der).unwrap();
613 assert_eq!(from_der.public_key(), public_key);
614 let from_pem = Ed25519PrivateKey::from_pem(&ed25519_pem).unwrap();
615 assert_eq!(from_pem.public_key(), public_key);
616
617 Secp256r1PrivateKey::from_der(&ed25519_der).unwrap_err();
619 Secp256r1PrivateKey::from_pem(&ed25519_pem).unwrap_err();
620 Secp256k1PrivateKey::from_der(&ed25519_der).unwrap_err();
621 Secp256k1PrivateKey::from_pem(&ed25519_pem).unwrap_err();
622
623 let keypair_from_der = SimpleKeypair::from_der(&ed25519_der).unwrap();
625 assert_eq!(ed25519_der, keypair_from_der.to_der().unwrap());
626 let keypair_from_pem = SimpleKeypair::from_pem(&ed25519_pem).unwrap();
627 assert_eq!(ed25519_pem, keypair_from_pem.to_pem().unwrap());
628
629 let verifying_key = signer.verifying_key();
633 let der = verifying_key.to_der().unwrap();
634 let pem = verifying_key.to_pem().unwrap();
635
636 let from_der = Ed25519VerifyingKey::from_der(&der).unwrap();
638 assert_eq!(from_der.public_key(), public_key);
639 let from_pem = Ed25519VerifyingKey::from_pem(&pem).unwrap();
640 assert_eq!(from_pem.public_key(), public_key);
641
642 Secp256r1VerifyingKey::from_der(&der).unwrap_err();
644 Secp256r1VerifyingKey::from_pem(&pem).unwrap_err();
645 Secp256k1VerifyingKey::from_der(&der).unwrap_err();
646 Secp256k1VerifyingKey::from_pem(&pem).unwrap_err();
647
648 let from_der = SimpleVerifiyingKey::from_der(&der).unwrap();
650 assert_eq!(der, from_der.to_der().unwrap());
651 let from_pem = SimpleVerifiyingKey::from_pem(&pem).unwrap();
652 assert_eq!(pem, from_pem.to_pem().unwrap());
653 }
654
655 #[proptest]
656 fn secp256r1_pem_der(signer: Secp256r1PrivateKey) {
657 let public_key = signer.public_key();
661 let secp256r1_der = signer.to_der().unwrap();
662 let secp256r1_pem = signer.to_pem().unwrap();
663
664 let from_der = Secp256r1PrivateKey::from_der(&secp256r1_der).unwrap();
666 assert_eq!(from_der.public_key(), public_key);
667 let from_pem = Secp256r1PrivateKey::from_pem(&secp256r1_pem).unwrap();
668 assert_eq!(from_pem.public_key(), public_key);
669
670 Ed25519PrivateKey::from_der(&secp256r1_der).unwrap_err();
672 Ed25519PrivateKey::from_pem(&secp256r1_pem).unwrap_err();
673 Secp256k1PrivateKey::from_der(&secp256r1_der).unwrap_err();
674 Secp256k1PrivateKey::from_pem(&secp256r1_pem).unwrap_err();
675
676 let keypair_from_der = SimpleKeypair::from_der(&secp256r1_der).unwrap();
678 assert_eq!(secp256r1_der, keypair_from_der.to_der().unwrap());
679 let keypair_from_pem = SimpleKeypair::from_pem(&secp256r1_pem).unwrap();
680 assert_eq!(secp256r1_pem, keypair_from_pem.to_pem().unwrap());
681
682 let verifying_key = signer.verifying_key();
686 let der = verifying_key.to_der().unwrap();
687 let pem = verifying_key.to_pem().unwrap();
688
689 let from_der = Secp256r1VerifyingKey::from_der(&der).unwrap();
691 assert_eq!(from_der.public_key(), public_key);
692 let from_pem = Secp256r1VerifyingKey::from_pem(&pem).unwrap();
693 assert_eq!(from_pem.public_key(), public_key);
694
695 Ed25519VerifyingKey::from_der(&der).unwrap_err();
697 Ed25519VerifyingKey::from_pem(&pem).unwrap_err();
698 Secp256k1VerifyingKey::from_der(&der).unwrap_err();
699 Secp256k1VerifyingKey::from_pem(&pem).unwrap_err();
700
701 let from_der = SimpleVerifiyingKey::from_der(&der).unwrap();
703 assert_eq!(der, from_der.to_der().unwrap());
704 let from_pem = SimpleVerifiyingKey::from_pem(&pem).unwrap();
705 assert_eq!(pem, from_pem.to_pem().unwrap());
706 }
707
708 #[proptest]
709 fn secp256k1_pem_der(signer: Secp256k1PrivateKey) {
710 let public_key = signer.public_key();
714 let secp256k1_der = signer.to_der().unwrap();
715 let secp256k1_pem = signer.to_pem().unwrap();
716
717 let from_der = Secp256k1PrivateKey::from_der(&secp256k1_der).unwrap();
719 assert_eq!(from_der.public_key(), public_key);
720 let from_pem = Secp256k1PrivateKey::from_pem(&secp256k1_pem).unwrap();
721 assert_eq!(from_pem.public_key(), public_key);
722
723 Ed25519PrivateKey::from_der(&secp256k1_der).unwrap_err();
725 Ed25519PrivateKey::from_pem(&secp256k1_pem).unwrap_err();
726 Secp256r1PrivateKey::from_der(&secp256k1_der).unwrap_err();
727 Secp256r1PrivateKey::from_pem(&secp256k1_pem).unwrap_err();
728
729 let keypair_from_der = SimpleKeypair::from_der(&secp256k1_der).unwrap();
731 assert_eq!(secp256k1_der, keypair_from_der.to_der().unwrap());
732 let keypair_from_pem = SimpleKeypair::from_pem(&secp256k1_pem).unwrap();
733 assert_eq!(secp256k1_pem, keypair_from_pem.to_pem().unwrap());
734
735 let verifying_key = signer.verifying_key();
739 let der = verifying_key.to_der().unwrap();
740 let pem = verifying_key.to_pem().unwrap();
741
742 let from_der = Secp256k1VerifyingKey::from_der(&der).unwrap();
744 assert_eq!(from_der.public_key(), public_key);
745 let from_pem = Secp256k1VerifyingKey::from_pem(&pem).unwrap();
746 assert_eq!(from_pem.public_key(), public_key);
747
748 Ed25519VerifyingKey::from_der(&der).unwrap_err();
750 Ed25519VerifyingKey::from_pem(&pem).unwrap_err();
751 Secp256r1VerifyingKey::from_der(&der).unwrap_err();
752 Secp256r1VerifyingKey::from_pem(&pem).unwrap_err();
753
754 let from_der = SimpleVerifiyingKey::from_der(&der).unwrap();
756 assert_eq!(der, from_der.to_der().unwrap());
757 let from_pem = SimpleVerifiyingKey::from_pem(&pem).unwrap();
758 assert_eq!(pem, from_pem.to_pem().unwrap());
759 }
760
761 #[proptest]
762 fn simple_verifying_key_derives_matching_address(
763 ed25519: Ed25519PrivateKey,
764 secp256k1: Secp256k1PrivateKey,
765 secp256r1: Secp256r1PrivateKey,
766 ) {
767 let expected = ed25519.public_key().derive_address();
770 let keypair = SimpleKeypair::from(ed25519);
771 assert_eq!(keypair.verifying_key().derive_address(), expected);
772
773 let expected = secp256k1.public_key().derive_address();
774 let keypair = SimpleKeypair::from(secp256k1);
775 assert_eq!(keypair.verifying_key().derive_address(), expected);
776
777 let expected = secp256r1.public_key().derive_address();
778 let keypair = SimpleKeypair::from(secp256r1);
779 assert_eq!(keypair.verifying_key().derive_address(), expected);
780 }
781
782 #[cfg(feature = "bech32")]
790 mod bech32 {
791 use super::*;
792 use sui_sdk_types::SignatureScheme;
793
794 #[cfg(target_arch = "wasm32")]
795 use wasm_bindgen_test::wasm_bindgen_test as test;
796
797 const UPSTREAM_ED25519_SUIPRIVKEY: &str =
802 "suiprivkey1qzdlfxn2qa2lj5uprl8pyhexs02sg2wrhdy7qaq50cqgnffw4c2477kg9h3";
803
804 #[proptest]
805 fn ed25519_round_trip(signer: Ed25519PrivateKey) {
806 let encoded = signer.to_suiprivkey().unwrap();
807 let decoded = Ed25519PrivateKey::from_suiprivkey(&encoded).unwrap();
808 assert_eq!(decoded.public_key(), signer.public_key());
809
810 let keypair = SimpleKeypair::from_suiprivkey(&encoded).unwrap();
812 assert_eq!(keypair.scheme(), signer.scheme());
813 assert_eq!(encoded, keypair.to_suiprivkey().unwrap());
814 }
815
816 #[proptest]
817 fn secp256k1_round_trip(signer: Secp256k1PrivateKey) {
818 let encoded = signer.to_suiprivkey().unwrap();
819 let decoded = Secp256k1PrivateKey::from_suiprivkey(&encoded).unwrap();
820 assert_eq!(decoded.public_key(), signer.public_key());
821
822 let keypair = SimpleKeypair::from_suiprivkey(&encoded).unwrap();
823 assert_eq!(keypair.scheme(), signer.scheme());
824 assert_eq!(encoded, keypair.to_suiprivkey().unwrap());
825 }
826
827 #[proptest]
828 fn secp256r1_round_trip(signer: Secp256r1PrivateKey) {
829 let encoded = signer.to_suiprivkey().unwrap();
830 let decoded = Secp256r1PrivateKey::from_suiprivkey(&encoded).unwrap();
831 assert_eq!(decoded.public_key(), signer.public_key());
832
833 let keypair = SimpleKeypair::from_suiprivkey(&encoded).unwrap();
834 assert_eq!(keypair.scheme(), signer.scheme());
835 assert_eq!(encoded, keypair.to_suiprivkey().unwrap());
836 }
837
838 #[test]
839 fn upstream_ed25519_vector_round_trips() {
840 let keypair = SimpleKeypair::from_suiprivkey(UPSTREAM_ED25519_SUIPRIVKEY).unwrap();
841 assert_eq!(keypair.scheme(), SignatureScheme::Ed25519);
842 assert_eq!(
843 keypair.to_suiprivkey().unwrap(),
844 UPSTREAM_ED25519_SUIPRIVKEY
845 );
846
847 Ed25519PrivateKey::from_suiprivkey(UPSTREAM_ED25519_SUIPRIVKEY).unwrap();
849 Secp256k1PrivateKey::from_suiprivkey(UPSTREAM_ED25519_SUIPRIVKEY).unwrap_err();
851 Secp256r1PrivateKey::from_suiprivkey(UPSTREAM_ED25519_SUIPRIVKEY).unwrap_err();
852 }
853
854 #[test]
855 fn rejects_wrong_hrp() {
856 let bytes = ::bech32::primitives::decode::CheckedHrpstring::new::<::bech32::Bech32>(
859 UPSTREAM_ED25519_SUIPRIVKEY,
860 )
861 .unwrap()
862 .byte_iter()
863 .collect::<Vec<_>>();
864 let wrong_hrp = ::bech32::Hrp::parse("notsui").unwrap();
865 let encoded = ::bech32::encode::<::bech32::Bech32>(wrong_hrp, &bytes).unwrap();
866
867 SimpleKeypair::from_suiprivkey(&encoded).unwrap_err();
868 Ed25519PrivateKey::from_suiprivkey(&encoded).unwrap_err();
869 }
870
871 #[test]
872 fn rejects_bech32m_checksum() {
873 let bytes = ::bech32::primitives::decode::CheckedHrpstring::new::<::bech32::Bech32>(
877 UPSTREAM_ED25519_SUIPRIVKEY,
878 )
879 .unwrap()
880 .byte_iter()
881 .collect::<Vec<_>>();
882 let hrp = ::bech32::Hrp::parse("suiprivkey").unwrap();
883 let bech32m = ::bech32::encode::<::bech32::Bech32m>(hrp, &bytes).unwrap();
884 assert_ne!(bech32m, UPSTREAM_ED25519_SUIPRIVKEY);
885
886 SimpleKeypair::from_suiprivkey(&bech32m).unwrap_err();
887 Ed25519PrivateKey::from_suiprivkey(&bech32m).unwrap_err();
888 }
889 }
890
891 mod base64 {
897 use super::*;
898 use sui_sdk_types::SignatureScheme;
899
900 #[cfg(target_arch = "wasm32")]
901 use wasm_bindgen_test::wasm_bindgen_test as test;
902
903 const UPSTREAM_ED25519_BASE64: &str = "AJv0mmoHVflTgR/OEl8mg9UEKcO7SeB0FH4AiaUurhVf";
908
909 #[proptest]
910 fn ed25519_round_trip(signer: Ed25519PrivateKey) {
911 let encoded = signer.to_base64();
912 let decoded = Ed25519PrivateKey::from_base64(&encoded).unwrap();
913 assert_eq!(decoded.public_key(), signer.public_key());
914
915 let keypair = SimpleKeypair::from_base64(&encoded).unwrap();
917 assert_eq!(keypair.scheme(), signer.scheme());
918 assert_eq!(encoded, keypair.to_base64());
919 }
920
921 #[proptest]
922 fn secp256k1_round_trip(signer: Secp256k1PrivateKey) {
923 let encoded = signer.to_base64();
924 let decoded = Secp256k1PrivateKey::from_base64(&encoded).unwrap();
925 assert_eq!(decoded.public_key(), signer.public_key());
926
927 let keypair = SimpleKeypair::from_base64(&encoded).unwrap();
928 assert_eq!(keypair.scheme(), signer.scheme());
929 assert_eq!(encoded, keypair.to_base64());
930 }
931
932 #[proptest]
933 fn secp256r1_round_trip(signer: Secp256r1PrivateKey) {
934 let encoded = signer.to_base64();
935 let decoded = Secp256r1PrivateKey::from_base64(&encoded).unwrap();
936 assert_eq!(decoded.public_key(), signer.public_key());
937
938 let keypair = SimpleKeypair::from_base64(&encoded).unwrap();
939 assert_eq!(keypair.scheme(), signer.scheme());
940 assert_eq!(encoded, keypair.to_base64());
941 }
942
943 #[test]
944 fn upstream_ed25519_vector_round_trips() {
945 let keypair = SimpleKeypair::from_base64(UPSTREAM_ED25519_BASE64).unwrap();
946 assert_eq!(keypair.scheme(), SignatureScheme::Ed25519);
947 assert_eq!(keypair.to_base64(), UPSTREAM_ED25519_BASE64);
948
949 Ed25519PrivateKey::from_base64(UPSTREAM_ED25519_BASE64).unwrap();
951 Secp256k1PrivateKey::from_base64(UPSTREAM_ED25519_BASE64).unwrap_err();
953 Secp256r1PrivateKey::from_base64(UPSTREAM_ED25519_BASE64).unwrap_err();
954 }
955
956 #[cfg(feature = "bech32")]
957 #[test]
958 fn agrees_with_suiprivkey_encoding() {
959 let keypair = SimpleKeypair::from_base64(UPSTREAM_ED25519_BASE64).unwrap();
962 let suiprivkey = keypair.to_suiprivkey().unwrap();
963 let round_tripped = SimpleKeypair::from_suiprivkey(&suiprivkey).unwrap();
964 assert_eq!(round_tripped.to_base64(), UPSTREAM_ED25519_BASE64);
965 }
966
967 #[test]
968 fn rejects_invalid_input() {
969 SimpleKeypair::from_base64("not base64!").unwrap_err();
971 Ed25519PrivateKey::from_base64("not base64!").unwrap_err();
972
973 SimpleKeypair::from_base64("").unwrap_err();
975
976 use base64ct::Encoding;
978 let payload = base64ct::Base64::decode_vec(UPSTREAM_ED25519_BASE64).unwrap();
979 let mut bad_flag_payload = payload.clone();
980 bad_flag_payload[0] = 0xff;
981 let bad_flag = base64ct::Base64::encode_string(&bad_flag_payload);
982 SimpleKeypair::from_base64(&bad_flag).unwrap_err();
983
984 let truncated = base64ct::Base64::encode_string(&payload[..16]);
986 SimpleKeypair::from_base64(&truncated).unwrap_err();
987 }
988 }
989}