1use anyhow::Result;
9use atproto_identity::key::{KeyData, KeyType, to_public};
10use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD};
11use elliptic_curve::{JwkEcKey, sec1::ToEncodedPoint};
12use serde::{Deserialize, Serialize};
13use serde_json::json;
14use sha2::{Digest, Sha256};
15
16use crate::errors::JWKError;
17
18#[cfg(feature = "zeroize")]
19use zeroize::{Zeroize, ZeroizeOnDrop};
20
21#[derive(Serialize, Deserialize, Clone, PartialEq)]
23#[cfg_attr(debug_assertions, derive(Debug))]
24#[cfg_attr(feature = "zeroize", derive(Zeroize, ZeroizeOnDrop))]
25pub struct WrappedJsonWebKey {
26 #[serde(skip_serializing_if = "Option::is_none", default)]
28 #[cfg_attr(feature = "zeroize", zeroize(skip))]
29 pub kid: Option<String>,
30
31 #[serde(skip_serializing_if = "Option::is_none", default)]
33 #[cfg_attr(feature = "zeroize", zeroize(skip))]
34 pub alg: Option<String>,
35
36 #[serde(rename = "use", skip_serializing_if = "Option::is_none")]
38 #[cfg_attr(feature = "zeroize", zeroize(skip))]
39 pub _use: Option<String>,
40
41 #[serde(flatten)]
43 pub jwk: JwkEcKey,
44}
45
46#[derive(Serialize, Deserialize, Clone)]
48pub struct WrappedJsonWebKeySet {
49 pub keys: Vec<WrappedJsonWebKey>,
51}
52
53pub fn generate(key_data: &KeyData) -> Result<WrappedJsonWebKey> {
55 let alg = match key_data.key_type() {
56 KeyType::P256Public => Some("ES256".to_string()),
57 KeyType::P256Private => Some("ES256".to_string()),
58 KeyType::P384Public => Some("ES384".to_string()),
59 KeyType::P384Private => Some("ES384".to_string()),
60 KeyType::K256Public => Some("ES256K".to_string()),
61 KeyType::K256Private => Some("ES256K".to_string()),
62 };
63 let jwk = key_data.try_into()?;
64
65 let public_key = to_public(key_data)?;
66 let kid = Some(public_key.to_string());
67
68 Ok(WrappedJsonWebKey {
69 kid,
70 alg,
71 jwk,
72 _use: Some("sig".to_string()),
73 })
74}
75
76pub fn to_key_data(wrapped_jwk: &WrappedJsonWebKey) -> Result<KeyData, JWKError> {
78 let curve = wrapped_jwk.jwk.crv();
80
81 match curve {
82 "P-256" => {
83 if let Ok(secret_key) = p256::SecretKey::try_from(&wrapped_jwk.jwk) {
85 Ok(KeyData::new(
86 KeyType::P256Private,
87 secret_key.to_bytes().to_vec(),
88 ))
89 } else if let Ok(public_key) = p256::PublicKey::try_from(&wrapped_jwk.jwk) {
90 let compressed = public_key.to_encoded_point(true);
92 Ok(KeyData::new(
93 KeyType::P256Public,
94 compressed.as_bytes().to_vec(),
95 ))
96 } else {
97 Err(JWKError::P256ConversionFailed)
98 }
99 }
100 "P-384" => {
101 if let Ok(secret_key) = p384::SecretKey::try_from(&wrapped_jwk.jwk) {
103 Ok(KeyData::new(
104 KeyType::P384Private,
105 secret_key.to_bytes().to_vec(),
106 ))
107 } else if let Ok(public_key) = p384::PublicKey::try_from(&wrapped_jwk.jwk) {
108 let compressed = public_key.to_encoded_point(true);
110 Ok(KeyData::new(
111 KeyType::P384Public,
112 compressed.as_bytes().to_vec(),
113 ))
114 } else {
115 Err(JWKError::P384ConversionFailed)
116 }
117 }
118 "secp256k1" => {
119 if let Ok(secret_key) = k256::SecretKey::try_from(&wrapped_jwk.jwk) {
121 Ok(KeyData::new(
122 KeyType::K256Private,
123 secret_key.to_bytes().to_vec(),
124 ))
125 } else if let Ok(public_key) = k256::PublicKey::try_from(&wrapped_jwk.jwk) {
126 let compressed = public_key.to_encoded_point(true);
128 Ok(KeyData::new(
129 KeyType::K256Public,
130 compressed.as_bytes().to_vec(),
131 ))
132 } else {
133 Err(JWKError::K256ConversionFailed)
134 }
135 }
136 _ => Err(JWKError::UnsupportedCurve {
137 curve: curve.to_string(),
138 }),
139 }
140}
141
142pub fn thumbprint(wrapped_jwk: &WrappedJsonWebKey) -> Result<String, JWKError> {
153 let jwk_json =
155 serde_json::to_value(&wrapped_jwk.jwk).map_err(|e| JWKError::SerializationError {
156 message: e.to_string(),
157 })?;
158
159 let jwk_obj = jwk_json
161 .as_object()
162 .ok_or_else(|| JWKError::SerializationError {
163 message: "JWK is not a JSON object".to_string(),
164 })?;
165
166 let kty =
168 jwk_obj
169 .get("kty")
170 .and_then(|v| v.as_str())
171 .ok_or_else(|| JWKError::MissingField {
172 field: "kty".to_string(),
173 })?;
174
175 if kty != "EC" {
176 return Err(JWKError::UnsupportedKeyType {
177 kty: kty.to_string(),
178 });
179 }
180
181 let crv = jwk_obj.get("crv").ok_or_else(|| JWKError::MissingField {
183 field: "crv".to_string(),
184 })?;
185 let x = jwk_obj.get("x").ok_or_else(|| JWKError::MissingField {
186 field: "x".to_string(),
187 })?;
188 let y = jwk_obj.get("y").ok_or_else(|| JWKError::MissingField {
189 field: "y".to_string(),
190 })?;
191
192 let thumbprint_json = json!({
194 "crv": crv,
195 "kty": kty,
196 "x": x,
197 "y": y
198 });
199
200 let canonical_json =
202 serde_json::to_string(&thumbprint_json).map_err(|e| JWKError::SerializationError {
203 message: e.to_string(),
204 })?;
205
206 let mut hasher = Sha256::new();
208 hasher.update(canonical_json.as_bytes());
209 let hash = hasher.finalize();
210
211 Ok(URL_SAFE_NO_PAD.encode(hash))
213}
214
215impl TryFrom<WrappedJsonWebKey> for KeyData {
220 type Error = anyhow::Error;
221
222 fn try_from(wrapped_jwk: WrappedJsonWebKey) -> Result<Self, Self::Error> {
223 to_key_data(&wrapped_jwk).map_err(Into::into)
224 }
225}
226
227impl TryFrom<&WrappedJsonWebKey> for KeyData {
232 type Error = anyhow::Error;
233
234 fn try_from(wrapped_jwk: &WrappedJsonWebKey) -> Result<Self, Self::Error> {
235 to_key_data(wrapped_jwk).map_err(Into::into)
236 }
237}
238
239#[cfg(test)]
240mod tests {
241 use super::*;
242 use atproto_identity::key::{generate_key, sign, to_public, validate};
243
244 #[test]
245 fn test_to_key_data_p256_private_round_trip() -> Result<()> {
246 let original_key = generate_key(KeyType::P256Private)?;
248
249 let wrapped_jwk = generate(&original_key)?;
251 assert_eq!(wrapped_jwk.alg, Some("ES256".to_string()));
252 assert_eq!(wrapped_jwk._use, Some("sig".to_string()));
253 assert_eq!(wrapped_jwk.jwk.crv(), "P-256");
254
255 let converted_key = to_key_data(&wrapped_jwk)?;
257
258 assert_eq!(*converted_key.key_type(), KeyType::P256Private);
260 assert_eq!(original_key.bytes(), converted_key.bytes());
261
262 let test_data = "P-256 private key round trip test".as_bytes();
264 let signature = sign(&converted_key, test_data)?;
265 validate(&converted_key, &signature, test_data)?;
266
267 Ok(())
268 }
269
270 #[test]
271 fn test_to_key_data_p256_public_round_trip() -> Result<()> {
272 let private_key = generate_key(KeyType::P256Private)?;
274 let original_public_key = to_public(&private_key)?;
275
276 let wrapped_jwk = generate(&original_public_key)?;
278 assert_eq!(wrapped_jwk.alg, Some("ES256".to_string()));
279 assert_eq!(wrapped_jwk.jwk.crv(), "P-256");
280
281 let converted_key = to_key_data(&wrapped_jwk)?;
283
284 assert_eq!(*converted_key.key_type(), KeyType::P256Public);
286 assert_eq!(original_public_key.bytes(), converted_key.bytes());
287
288 let test_data = "P-256 public key round trip test".as_bytes();
290 let signature = sign(&private_key, test_data)?;
291 validate(&converted_key, &signature, test_data)?;
292
293 Ok(())
294 }
295
296 #[test]
297 fn test_to_key_data_p384_private_round_trip() -> Result<()> {
298 let original_key = generate_key(KeyType::P384Private)?;
300
301 let wrapped_jwk = generate(&original_key)?;
303 assert_eq!(wrapped_jwk.alg, Some("ES384".to_string()));
304 assert_eq!(wrapped_jwk._use, Some("sig".to_string()));
305 assert_eq!(wrapped_jwk.jwk.crv(), "P-384");
306
307 let converted_key = to_key_data(&wrapped_jwk)?;
309
310 assert_eq!(*converted_key.key_type(), KeyType::P384Private);
312 assert_eq!(original_key.bytes(), converted_key.bytes());
313
314 let test_data = "P-384 private key round trip test".as_bytes();
316 let signature = sign(&converted_key, test_data)?;
317 validate(&converted_key, &signature, test_data)?;
318
319 Ok(())
320 }
321
322 #[test]
323 fn test_to_key_data_p384_public_round_trip() -> Result<()> {
324 let private_key = generate_key(KeyType::P384Private)?;
326 let original_public_key = to_public(&private_key)?;
327
328 let wrapped_jwk = generate(&original_public_key)?;
330 assert_eq!(wrapped_jwk.alg, Some("ES384".to_string()));
331 assert_eq!(wrapped_jwk.jwk.crv(), "P-384");
332
333 let converted_key = to_key_data(&wrapped_jwk)?;
335
336 assert_eq!(*converted_key.key_type(), KeyType::P384Public);
338 assert_eq!(original_public_key.bytes(), converted_key.bytes());
339
340 let test_data = "P-384 public key round trip test".as_bytes();
342 let signature = sign(&private_key, test_data)?;
343 validate(&converted_key, &signature, test_data)?;
344
345 Ok(())
346 }
347
348 #[test]
349 fn test_to_key_data_k256_private_round_trip() -> Result<()> {
350 let original_key = generate_key(KeyType::K256Private)?;
352
353 let wrapped_jwk = generate(&original_key)?;
355 assert_eq!(wrapped_jwk.alg, Some("ES256K".to_string()));
356 assert_eq!(wrapped_jwk._use, Some("sig".to_string()));
357 assert_eq!(wrapped_jwk.jwk.crv(), "secp256k1");
358
359 let converted_key = to_key_data(&wrapped_jwk)?;
361
362 assert_eq!(*converted_key.key_type(), KeyType::K256Private);
364 assert_eq!(original_key.bytes(), converted_key.bytes());
365
366 let test_data = "K-256 private key round trip test".as_bytes();
368 let signature = sign(&converted_key, test_data)?;
369 validate(&converted_key, &signature, test_data)?;
370
371 Ok(())
372 }
373
374 #[test]
375 fn test_to_key_data_k256_public_round_trip() -> Result<()> {
376 let private_key = generate_key(KeyType::K256Private)?;
378 let original_public_key = to_public(&private_key)?;
379
380 let wrapped_jwk = generate(&original_public_key)?;
382 assert_eq!(wrapped_jwk.alg, Some("ES256K".to_string()));
383 assert_eq!(wrapped_jwk.jwk.crv(), "secp256k1");
384
385 let converted_key = to_key_data(&wrapped_jwk)?;
387
388 assert_eq!(*converted_key.key_type(), KeyType::K256Public);
390 assert_eq!(original_public_key.bytes(), converted_key.bytes());
391
392 let test_data = "K-256 public key round trip test".as_bytes();
394 let signature = sign(&private_key, test_data)?;
395 validate(&converted_key, &signature, test_data)?;
396
397 Ok(())
398 }
399
400 #[test]
401 fn test_to_key_data_multiple_round_trips() -> Result<()> {
402 for _ in 0..3 {
404 let p256_private = generate_key(KeyType::P256Private)?;
406 let p256_private_jwk = generate(&p256_private)?;
407 let p256_private_converted = to_key_data(&p256_private_jwk)?;
408 assert_eq!(p256_private.bytes(), p256_private_converted.bytes());
409
410 let p256_public = to_public(&p256_private)?;
412 let p256_public_jwk = generate(&p256_public)?;
413 let p256_public_converted = to_key_data(&p256_public_jwk)?;
414 assert_eq!(p256_public.bytes(), p256_public_converted.bytes());
415
416 let p384_private = generate_key(KeyType::P384Private)?;
418 let p384_private_jwk = generate(&p384_private)?;
419 let p384_private_converted = to_key_data(&p384_private_jwk)?;
420 assert_eq!(p384_private.bytes(), p384_private_converted.bytes());
421
422 let p384_public = to_public(&p384_private)?;
424 let p384_public_jwk = generate(&p384_public)?;
425 let p384_public_converted = to_key_data(&p384_public_jwk)?;
426 assert_eq!(p384_public.bytes(), p384_public_converted.bytes());
427
428 let k256_private = generate_key(KeyType::K256Private)?;
430 let k256_private_jwk = generate(&k256_private)?;
431 let k256_private_converted = to_key_data(&k256_private_jwk)?;
432 assert_eq!(k256_private.bytes(), k256_private_converted.bytes());
433
434 let k256_public = to_public(&k256_private)?;
436 let k256_public_jwk = generate(&k256_public)?;
437 let k256_public_converted = to_key_data(&k256_public_jwk)?;
438 assert_eq!(k256_public.bytes(), k256_public_converted.bytes());
439 }
440
441 Ok(())
442 }
443
444 #[test]
445 fn test_to_key_data_cross_curve_verification() -> Result<()> {
446 let p256_private = generate_key(KeyType::P256Private)?;
448 let p384_private = generate_key(KeyType::P384Private)?;
449 let k256_private = generate_key(KeyType::K256Private)?;
450
451 let p256_jwk = generate(&p256_private)?;
453 let p384_jwk = generate(&p384_private)?;
454 let k256_jwk = generate(&k256_private)?;
455
456 let p256_converted = to_key_data(&p256_jwk)?;
457 let p384_converted = to_key_data(&p384_jwk)?;
458 let k256_converted = to_key_data(&k256_jwk)?;
459
460 let test_data = "Cross-curve verification test".as_bytes();
462
463 let p256_signature = sign(&p256_converted, test_data)?;
464 let p384_signature = sign(&p384_converted, test_data)?;
465 let k256_signature = sign(&k256_converted, test_data)?;
466
467 validate(&p256_converted, &p256_signature, test_data)?;
469 validate(&p384_converted, &p384_signature, test_data)?;
470 validate(&k256_converted, &k256_signature, test_data)?;
471
472 assert!(validate(&p256_converted, &p384_signature, test_data).is_err());
474 assert!(validate(&p256_converted, &k256_signature, test_data).is_err());
475 assert!(validate(&p384_converted, &p256_signature, test_data).is_err());
476 assert!(validate(&p384_converted, &k256_signature, test_data).is_err());
477 assert!(validate(&k256_converted, &p256_signature, test_data).is_err());
478 assert!(validate(&k256_converted, &p384_signature, test_data).is_err());
479
480 Ok(())
481 }
482
483 #[test]
484 fn test_to_key_data_algorithm_consistency() -> Result<()> {
485 let p256_key = generate_key(KeyType::P256Private)?;
487 let p384_key = generate_key(KeyType::P384Private)?;
488 let k256_key = generate_key(KeyType::K256Private)?;
489
490 let p256_jwk = generate(&p256_key)?;
491 let p384_jwk = generate(&p384_key)?;
492 let k256_jwk = generate(&k256_key)?;
493
494 assert_eq!(p256_jwk.alg, Some("ES256".to_string()));
496 assert_eq!(p384_jwk.alg, Some("ES384".to_string()));
497 assert_eq!(k256_jwk.alg, Some("ES256K".to_string()));
498
499 assert_eq!(p256_jwk.jwk.crv(), "P-256");
501 assert_eq!(p384_jwk.jwk.crv(), "P-384");
502 assert_eq!(k256_jwk.jwk.crv(), "secp256k1");
503
504 let p256_converted = to_key_data(&p256_jwk)?;
506 let p384_converted = to_key_data(&p384_jwk)?;
507 let k256_converted = to_key_data(&k256_jwk)?;
508
509 assert_eq!(*p256_converted.key_type(), KeyType::P256Private);
510 assert_eq!(*p384_converted.key_type(), KeyType::P384Private);
511 assert_eq!(*k256_converted.key_type(), KeyType::K256Private);
512
513 Ok(())
514 }
515
516 #[test]
517 fn test_to_key_data_key_sizes() -> Result<()> {
518 let p256_private = generate_key(KeyType::P256Private)?;
520 let p384_private = generate_key(KeyType::P384Private)?;
521 let k256_private = generate_key(KeyType::K256Private)?;
522
523 let p256_public = to_public(&p256_private)?;
524 let p384_public = to_public(&p384_private)?;
525 let k256_public = to_public(&k256_private)?;
526
527 let keys = [
529 (&p256_private, 32), (&p384_private, 48), (&k256_private, 32), (&p256_public, 33), (&p384_public, 49), (&k256_public, 33), ];
536
537 for (original_key, expected_size) in keys {
538 let jwk = generate(original_key)?;
539 let converted_key = to_key_data(&jwk)?;
540
541 assert_eq!(
542 converted_key.bytes().len(),
543 expected_size,
544 "Key size mismatch for {:?}",
545 original_key.key_type()
546 );
547 assert_eq!(original_key.bytes(), converted_key.bytes());
548 }
549
550 Ok(())
551 }
552
553 #[test]
554 fn test_to_key_data_did_string_consistency() -> Result<()> {
555 let test_keys = [
557 generate_key(KeyType::P256Private)?,
558 generate_key(KeyType::P384Private)?,
559 generate_key(KeyType::K256Private)?,
560 ];
561
562 for original_key in test_keys {
563 let original_did = format!("{}", original_key);
564
565 let jwk = generate(&original_key)?;
567 let converted_key = to_key_data(&jwk)?;
568 let converted_did = format!("{}", converted_key);
569
570 assert_eq!(
571 original_did,
572 converted_did,
573 "DID string mismatch for {:?}",
574 original_key.key_type()
575 );
576
577 let public_key = to_public(&original_key)?;
579 let public_did = format!("{}", public_key);
580
581 let public_jwk = generate(&public_key)?;
582 let converted_public_key = to_key_data(&public_jwk)?;
583 let converted_public_did = format!("{}", converted_public_key);
584
585 assert_eq!(
586 public_did,
587 converted_public_did,
588 "Public DID string mismatch for {:?}",
589 public_key.key_type()
590 );
591 }
592
593 Ok(())
594 }
595
596 #[test]
597 fn test_to_key_data_unsupported_curve() {
598 let valid_key = generate_key(KeyType::P256Private).unwrap();
606 let valid_jwk = generate(&valid_key).unwrap();
607
608 let result = to_key_data(&valid_jwk);
610 assert!(result.is_ok());
611
612 }
616
617 #[test]
618 fn test_to_key_data_invalid_jwk_conversion() {
619 use serde_json::json;
624
625 let invalid_jwk_json = json!({
627 "kty": "EC",
628 "crv": "P-256",
629 "x": "invalid-base64-data!!!",
630 "y": "also-invalid-base64!!!"
631 });
632
633 let _jwk_result: Result<elliptic_curve::JwkEcKey, _> =
635 serde_json::from_value(invalid_jwk_json);
636 let p256_key = generate_key(KeyType::P256Private).unwrap();
641 let valid_jwk = generate(&p256_key).unwrap();
642
643 let result = to_key_data(&valid_jwk);
645 assert!(result.is_ok());
646 }
647
648 #[test]
649 fn test_to_key_data_round_trip_with_existing_keys() -> Result<()> {
650 use atproto_identity::key::identify_key;
652
653 let test_keys = [
654 "did:key:z42tnbHmmnhF11nwSnp5kQJbcZQw2Vbw5WF3ABDSxPtDgU2o", "did:key:zDnaeXduWbJ1b1Kgjf3uCdCpMDF1LEDizUiyxAxGwerou3Nh2", "did:key:z3vLY4nbXy2rV4Qr65gUtfnSF3A8Be7gmYzUiCX6eo2PR1Rt", "did:key:zQ3shNzMp4oaaQ1gQRzCxMGXFrSW3NEM1M9T6KCY9eA7HhyEA", ];
659
660 for key_did in test_keys {
661 let original_key = identify_key(key_did)?;
662 let jwk = generate(&original_key)?;
663 let converted_key = to_key_data(&jwk)?;
664
665 assert_eq!(*original_key.key_type(), *converted_key.key_type());
667 assert_eq!(original_key.bytes(), converted_key.bytes());
668
669 let original_did = format!("{}", original_key);
671 let converted_did = format!("{}", converted_key);
672 assert_eq!(original_did, converted_did);
673 }
674
675 Ok(())
676 }
677
678 #[test]
679 fn test_to_key_data_metadata_preservation() -> Result<()> {
680 let test_keys = [
682 (generate_key(KeyType::P256Private)?, "ES256", "P-256"),
683 (generate_key(KeyType::P384Private)?, "ES384", "P-384"),
684 (generate_key(KeyType::K256Private)?, "ES256K", "secp256k1"),
685 ];
686
687 for (key, expected_alg, expected_crv) in test_keys {
688 let jwk = generate(&key)?;
689
690 assert_eq!(jwk.alg, Some(expected_alg.to_string()));
692 assert_eq!(jwk._use, Some("sig".to_string()));
693 assert_eq!(jwk.jwk.crv(), expected_crv);
694 assert!(jwk.kid.is_some());
695
696 let converted_key = to_key_data(&jwk)?;
698 assert_eq!(key.bytes(), converted_key.bytes());
699 }
700
701 Ok(())
702 }
703
704 #[test]
705 fn test_to_key_data_performance_stress() -> Result<()> {
706 use std::time::Instant;
708
709 let start = Instant::now();
710
711 for _ in 0..100 {
712 let p256_key = generate_key(KeyType::P256Private)?;
714 let p256_jwk = generate(&p256_key)?;
715 let p256_converted = to_key_data(&p256_jwk)?;
716 assert_eq!(p256_key.bytes(), p256_converted.bytes());
717
718 let p384_key = generate_key(KeyType::P384Private)?;
720 let p384_jwk = generate(&p384_key)?;
721 let p384_converted = to_key_data(&p384_jwk)?;
722 assert_eq!(p384_key.bytes(), p384_converted.bytes());
723
724 let k256_key = generate_key(KeyType::K256Private)?;
726 let k256_jwk = generate(&k256_key)?;
727 let k256_converted = to_key_data(&k256_jwk)?;
728 assert_eq!(k256_key.bytes(), k256_converted.bytes());
729 }
730
731 let duration = start.elapsed();
732 println!("300 round-trip conversions completed in: {:?}", duration);
733
734 assert!(
736 duration.as_millis() < 5000,
737 "Performance test took too long: {:?}",
738 duration
739 );
740
741 Ok(())
742 }
743
744 #[test]
745 fn test_to_key_data_serialization_consistency() -> Result<()> {
746 let test_keys = [
748 generate_key(KeyType::P256Private)?,
749 generate_key(KeyType::P384Private)?,
750 generate_key(KeyType::K256Private)?,
751 ];
752
753 for original_key in test_keys {
754 let jwk = generate(&original_key)?;
756
757 let json_string = serde_json::to_string(&jwk)?;
759 let deserialized_jwk: WrappedJsonWebKey = serde_json::from_str(&json_string)?;
760
761 let converted_from_original = to_key_data(&jwk)?;
763 let converted_from_deserialized = to_key_data(&deserialized_jwk)?;
764
765 assert_eq!(
767 *converted_from_original.key_type(),
768 *converted_from_deserialized.key_type()
769 );
770 assert_eq!(
771 converted_from_original.bytes(),
772 converted_from_deserialized.bytes()
773 );
774 assert_eq!(original_key.bytes(), converted_from_original.bytes());
775 }
776
777 Ok(())
778 }
779
780 #[test]
781 fn test_to_key_data_comprehensive_workflow() -> Result<()> {
782 println!("\n=== WrappedJsonWebKey to KeyData Comprehensive Test ===");
783
784 let test_cases = [
786 ("P-256 private", KeyType::P256Private),
787 ("P-384 private", KeyType::P384Private),
788 ("K-256 private", KeyType::K256Private),
789 ];
790
791 for (description, key_type) in test_cases {
792 println!("Testing {}", description);
793
794 let original_private = generate_key(key_type)?;
796 let original_public = to_public(&original_private)?;
797
798 let private_jwk = generate(&original_private)?;
800 let public_jwk = generate(&original_public)?;
801
802 let converted_private = to_key_data(&private_jwk)?;
804 let converted_public = to_key_data(&public_jwk)?;
805
806 assert_eq!(original_private.bytes(), converted_private.bytes());
808 assert_eq!(original_public.bytes(), converted_public.bytes());
809
810 let test_message = format!("Test data for {}", description);
812 let test_data = test_message.as_bytes();
813
814 let signature_original = sign(&original_private, test_data)?;
815 let signature_converted = sign(&converted_private, test_data)?;
816
817 validate(&original_public, &signature_original, test_data)?;
819 validate(&converted_public, &signature_original, test_data)?;
820 validate(&original_public, &signature_converted, test_data)?;
821 validate(&converted_public, &signature_converted, test_data)?;
822
823 assert_eq!(
825 format!("{}", original_private),
826 format!("{}", converted_private)
827 );
828 assert_eq!(
829 format!("{}", original_public),
830 format!("{}", converted_public)
831 );
832
833 println!(" ✓ {} passed all tests", description);
834 }
835
836 println!("=== All comprehensive tests completed successfully! ===\n");
837
838 Ok(())
839 }
840
841 #[test]
844 fn test_try_from_owned_p256_private() -> Result<()> {
845 let original_key = generate_key(KeyType::P256Private)?;
846 let wrapped_jwk = generate(&original_key)?;
847
848 let converted_key: KeyData = wrapped_jwk.try_into()?;
850
851 assert_eq!(*converted_key.key_type(), KeyType::P256Private);
852 assert_eq!(original_key.bytes(), converted_key.bytes());
853
854 Ok(())
855 }
856
857 #[test]
858 fn test_try_from_reference_p256_private() -> Result<()> {
859 let original_key = generate_key(KeyType::P256Private)?;
860 let wrapped_jwk = generate(&original_key)?;
861
862 let converted_key: KeyData = (&wrapped_jwk).try_into()?;
864
865 assert_eq!(*converted_key.key_type(), KeyType::P256Private);
866 assert_eq!(original_key.bytes(), converted_key.bytes());
867
868 Ok(())
869 }
870
871 #[test]
872 fn test_try_from_explicit_p256_private() -> Result<()> {
873 let original_key = generate_key(KeyType::P256Private)?;
874 let wrapped_jwk = generate(&original_key)?;
875
876 let converted_owned = KeyData::try_from(wrapped_jwk.clone())?;
878 let converted_ref = KeyData::try_from(&wrapped_jwk)?;
879
880 assert_eq!(*converted_owned.key_type(), KeyType::P256Private);
881 assert_eq!(*converted_ref.key_type(), KeyType::P256Private);
882 assert_eq!(original_key.bytes(), converted_owned.bytes());
883 assert_eq!(original_key.bytes(), converted_ref.bytes());
884 assert_eq!(converted_owned.bytes(), converted_ref.bytes());
885
886 Ok(())
887 }
888
889 #[test]
890 fn test_try_into_vs_to_key_data_consistency() -> Result<()> {
891 let test_keys = [
893 generate_key(KeyType::P256Private)?,
894 generate_key(KeyType::P384Private)?,
895 generate_key(KeyType::K256Private)?,
896 ];
897
898 for original_key in test_keys {
899 let public_key = to_public(&original_key)?;
900
901 for key in [&original_key, &public_key] {
902 let wrapped_jwk = generate(key)?;
903
904 let from_to_key_data = to_key_data(&wrapped_jwk)?;
906 let from_try_from_owned: KeyData = wrapped_jwk.clone().try_into()?;
907 let from_try_from_ref: KeyData = (&wrapped_jwk).try_into()?;
908 let from_explicit_owned = KeyData::try_from(wrapped_jwk.clone())?;
909 let from_explicit_ref = KeyData::try_from(&wrapped_jwk)?;
910
911 assert_eq!(from_to_key_data.key_type(), from_try_from_owned.key_type());
913 assert_eq!(from_to_key_data.key_type(), from_try_from_ref.key_type());
914 assert_eq!(from_to_key_data.key_type(), from_explicit_owned.key_type());
915 assert_eq!(from_to_key_data.key_type(), from_explicit_ref.key_type());
916
917 assert_eq!(from_to_key_data.bytes(), from_try_from_owned.bytes());
918 assert_eq!(from_to_key_data.bytes(), from_try_from_ref.bytes());
919 assert_eq!(from_to_key_data.bytes(), from_explicit_owned.bytes());
920 assert_eq!(from_to_key_data.bytes(), from_explicit_ref.bytes());
921 }
922 }
923
924 Ok(())
925 }
926
927 #[test]
928 fn test_trait_implementations_all_curves() -> Result<()> {
929 let test_cases = [
931 (KeyType::P256Private, "P-256 private"),
932 (KeyType::P384Private, "P-384 private"),
933 (KeyType::K256Private, "K-256 private"),
934 ];
935
936 for (key_type, description) in test_cases {
937 let private_key = generate_key(key_type)?;
939 let private_jwk = generate(&private_key)?;
940
941 let converted_private_owned: KeyData = private_jwk.clone().try_into()?;
943 let converted_private_ref: KeyData = (&private_jwk).try_into()?;
944
945 assert_eq!(
946 private_key.bytes(),
947 converted_private_owned.bytes(),
948 "Owned conversion failed for {}",
949 description
950 );
951 assert_eq!(
952 private_key.bytes(),
953 converted_private_ref.bytes(),
954 "Reference conversion failed for {}",
955 description
956 );
957
958 let public_key = to_public(&private_key)?;
960 let public_jwk = generate(&public_key)?;
961
962 let converted_public_owned: KeyData = public_jwk.clone().try_into()?;
964 let converted_public_ref: KeyData = (&public_jwk).try_into()?;
965
966 assert_eq!(
967 public_key.bytes(),
968 converted_public_owned.bytes(),
969 "Public owned conversion failed for {}",
970 description
971 );
972 assert_eq!(
973 public_key.bytes(),
974 converted_public_ref.bytes(),
975 "Public reference conversion failed for {}",
976 description
977 );
978
979 let test_data = format!("Trait test for {}", description);
981 let test_bytes = test_data.as_bytes();
982
983 let signature = sign(&converted_private_owned, test_bytes)?;
984 validate(&converted_public_owned, &signature, test_bytes)?;
985 validate(&converted_public_ref, &signature, test_bytes)?;
986 }
987
988 Ok(())
989 }
990
991 #[test]
992 fn test_trait_error_handling() -> Result<()> {
993 let p256_key = generate_key(KeyType::P256Private)?;
995 let valid_jwk = generate(&p256_key)?;
996
997 let _: KeyData = valid_jwk.clone().try_into()?;
999 let _: KeyData = (&valid_jwk).try_into()?;
1000 let _ = KeyData::try_from(valid_jwk.clone())?;
1001 let _ = KeyData::try_from(&valid_jwk)?;
1002
1003 Ok(())
1007 }
1008
1009 #[test]
1010 fn test_trait_ownership_semantics() -> Result<()> {
1011 let original_key = generate_key(KeyType::P256Private)?;
1013 let wrapped_jwk = generate(&original_key)?;
1014
1015 let cloned_jwk = wrapped_jwk.clone();
1017 let converted_owned: KeyData = cloned_jwk.try_into()?;
1018
1019 let converted_ref: KeyData = (&wrapped_jwk).try_into()?;
1021
1022 let converted_ref2: KeyData = (&wrapped_jwk).try_into()?;
1024
1025 assert_eq!(converted_owned.bytes(), converted_ref.bytes());
1027 assert_eq!(converted_ref.bytes(), converted_ref2.bytes());
1028 assert_eq!(original_key.bytes(), converted_owned.bytes());
1029
1030 Ok(())
1031 }
1032
1033 #[test]
1034 fn test_trait_type_inference() -> Result<()> {
1035 let original_key = generate_key(KeyType::K256Private)?;
1037 let wrapped_jwk = generate(&original_key)?;
1038
1039 let converted1 = KeyData::try_from(wrapped_jwk.clone())?;
1041 let converted2 = KeyData::try_from(&wrapped_jwk)?;
1042
1043 let converted3: Result<KeyData, _> = wrapped_jwk.clone().try_into();
1045 let converted3 = converted3?;
1046
1047 let converted4: Result<KeyData, _> = (&wrapped_jwk).try_into();
1048 let converted4 = converted4?;
1049
1050 assert_eq!(converted1.bytes(), converted2.bytes());
1052 assert_eq!(converted2.bytes(), converted3.bytes());
1053 assert_eq!(converted3.bytes(), converted4.bytes());
1054 assert_eq!(original_key.bytes(), converted1.bytes());
1055
1056 Ok(())
1057 }
1058
1059 #[test]
1060 fn test_trait_comprehensive_workflow() -> Result<()> {
1061 println!("\n=== TryFrom/TryInto Trait Implementation Test ===");
1062
1063 let test_cases = [
1065 ("P-256", KeyType::P256Private),
1066 ("P-384", KeyType::P384Private),
1067 ("K-256", KeyType::K256Private),
1068 ];
1069
1070 for (curve_name, key_type) in test_cases {
1071 println!("Testing {} trait implementations", curve_name);
1072
1073 let original_private = generate_key(key_type)?;
1075 let original_public = to_public(&original_private)?;
1076
1077 let private_jwk = generate(&original_private)?;
1079 let public_jwk = generate(&original_public)?;
1080
1081 println!(" Testing TryFrom<WrappedJsonWebKey>");
1083 let private_from_owned = KeyData::try_from(private_jwk.clone())?;
1084 let public_from_owned = KeyData::try_from(public_jwk.clone())?;
1085
1086 println!(" Testing TryFrom<&WrappedJsonWebKey>");
1087 let private_from_ref = KeyData::try_from(&private_jwk)?;
1088 let public_from_ref = KeyData::try_from(&public_jwk)?;
1089
1090 println!(" Testing TryInto<KeyData> for WrappedJsonWebKey");
1091 let private_into_owned: KeyData = private_jwk.clone().try_into()?;
1092 let public_into_owned: KeyData = public_jwk.clone().try_into()?;
1093
1094 println!(" Testing TryInto<KeyData> for &WrappedJsonWebKey");
1095 let private_into_ref: KeyData = (&private_jwk).try_into()?;
1096 let public_into_ref: KeyData = (&public_jwk).try_into()?;
1097
1098 let private_results = [
1100 &private_from_owned,
1101 &private_from_ref,
1102 &private_into_owned,
1103 &private_into_ref,
1104 ];
1105 let public_results = [
1106 &public_from_owned,
1107 &public_from_ref,
1108 &public_into_owned,
1109 &public_into_ref,
1110 ];
1111
1112 for result in &private_results[1..] {
1113 assert_eq!(private_results[0].bytes(), result.bytes());
1114 assert_eq!(private_results[0].key_type(), result.key_type());
1115 }
1116
1117 for result in &public_results[1..] {
1118 assert_eq!(public_results[0].bytes(), result.bytes());
1119 assert_eq!(public_results[0].key_type(), result.key_type());
1120 }
1121
1122 assert_eq!(original_private.bytes(), private_results[0].bytes());
1124 assert_eq!(original_public.bytes(), public_results[0].bytes());
1125
1126 let test_data = format!("{} trait test", curve_name);
1128 let test_bytes = test_data.as_bytes();
1129
1130 let signature = sign(&private_from_owned, test_bytes)?;
1131 validate(&public_from_owned, &signature, test_bytes)?;
1132 validate(&public_into_ref, &signature, test_bytes)?;
1133
1134 println!(" ✓ {} trait implementations passed all tests", curve_name);
1135 }
1136
1137 println!("=== All trait implementation tests completed successfully! ===\n");
1138
1139 Ok(())
1140 }
1141
1142 #[test]
1143 fn test_trait_usage_examples() -> Result<()> {
1144 let original_key = generate_key(KeyType::P256Private)?;
1146 let wrapped_jwk = generate(&original_key)?;
1147
1148 let converted1: KeyData = wrapped_jwk.clone().try_into()?;
1150
1151 let converted2: KeyData = (&wrapped_jwk).try_into()?;
1153
1154 let converted3 = KeyData::try_from(wrapped_jwk.clone())?;
1156 let converted4 = KeyData::try_from(&wrapped_jwk)?;
1157
1158 let converted5 = to_key_data(&wrapped_jwk)?;
1160
1161 let results = [
1163 &converted1,
1164 &converted2,
1165 &converted3,
1166 &converted4,
1167 &converted5,
1168 ];
1169 for result in &results[1..] {
1170 assert_eq!(converted1.bytes(), result.bytes());
1171 assert_eq!(converted1.key_type(), result.key_type());
1172 }
1173
1174 assert_eq!(original_key.bytes(), converted1.bytes());
1176 assert_eq!(*original_key.key_type(), *converted1.key_type());
1177
1178 println!("✓ All trait usage examples work correctly");
1179 Ok(())
1180 }
1181
1182 #[test]
1185 fn test_thumbprint_p256() -> Result<()> {
1186 let key = generate_key(KeyType::P256Private)?;
1187 let wrapped_jwk = generate(&key)?;
1188
1189 let tp = thumbprint(&wrapped_jwk)?;
1190
1191 assert!(!tp.is_empty());
1193 assert!(tp.len() > 20); assert!(!tp.contains('=')); assert!(!tp.contains('+')); assert!(!tp.contains('/')); Ok(())
1199 }
1200
1201 #[test]
1202 fn test_thumbprint_p384() -> Result<()> {
1203 let key = generate_key(KeyType::P384Private)?;
1204 let wrapped_jwk = generate(&key)?;
1205
1206 let tp = thumbprint(&wrapped_jwk)?;
1207
1208 assert!(!tp.is_empty());
1210 assert!(tp.len() > 20);
1211 assert!(!tp.contains('='));
1212 assert!(!tp.contains('+'));
1213 assert!(!tp.contains('/'));
1214
1215 Ok(())
1216 }
1217
1218 #[test]
1219 fn test_thumbprint_k256() -> Result<()> {
1220 let key = generate_key(KeyType::K256Private)?;
1221 let wrapped_jwk = generate(&key)?;
1222
1223 let tp = thumbprint(&wrapped_jwk)?;
1224
1225 assert!(!tp.is_empty());
1227 assert!(tp.len() > 20);
1228 assert!(!tp.contains('='));
1229 assert!(!tp.contains('+'));
1230 assert!(!tp.contains('/'));
1231
1232 Ok(())
1233 }
1234
1235 #[test]
1236 fn test_thumbprint_consistency() -> Result<()> {
1237 let key = generate_key(KeyType::P256Private)?;
1239 let wrapped_jwk = generate(&key)?;
1240
1241 let tp1 = thumbprint(&wrapped_jwk)?;
1242 let tp2 = thumbprint(&wrapped_jwk)?;
1243 let tp3 = thumbprint(&wrapped_jwk)?;
1244
1245 assert_eq!(tp1, tp2);
1246 assert_eq!(tp2, tp3);
1247
1248 Ok(())
1249 }
1250
1251 #[test]
1252 fn test_thumbprint_different_keys_different_thumbprints() -> Result<()> {
1253 let key1 = generate_key(KeyType::P256Private)?;
1255 let key2 = generate_key(KeyType::P256Private)?;
1256
1257 let jwk1 = generate(&key1)?;
1258 let jwk2 = generate(&key2)?;
1259
1260 let tp1 = thumbprint(&jwk1)?;
1261 let tp2 = thumbprint(&jwk2)?;
1262
1263 assert_ne!(tp1, tp2);
1264
1265 Ok(())
1266 }
1267
1268 #[test]
1269 fn test_thumbprint_private_vs_public_same_thumbprint() -> Result<()> {
1270 let private_key = generate_key(KeyType::P256Private)?;
1273 let public_key = to_public(&private_key)?;
1274
1275 let private_jwk = generate(&private_key)?;
1276 let public_jwk = generate(&public_key)?;
1277
1278 let private_tp = thumbprint(&private_jwk)?;
1279 let public_tp = thumbprint(&public_jwk)?;
1280
1281 assert_eq!(private_tp, public_tp);
1282
1283 Ok(())
1284 }
1285
1286 #[test]
1287 fn test_thumbprint_cross_curve_different() -> Result<()> {
1288 let p256_key = generate_key(KeyType::P256Private)?;
1290 let p384_key = generate_key(KeyType::P384Private)?;
1291 let k256_key = generate_key(KeyType::K256Private)?;
1292
1293 let p256_jwk = generate(&p256_key)?;
1294 let p384_jwk = generate(&p384_key)?;
1295 let k256_jwk = generate(&k256_key)?;
1296
1297 let p256_tp = thumbprint(&p256_jwk)?;
1298 let p384_tp = thumbprint(&p384_jwk)?;
1299 let k256_tp = thumbprint(&k256_jwk)?;
1300
1301 assert_ne!(p256_tp, p384_tp);
1302 assert_ne!(p256_tp, k256_tp);
1303 assert_ne!(p384_tp, k256_tp);
1304
1305 Ok(())
1306 }
1307
1308 #[test]
1309 fn test_thumbprint_deterministic() -> Result<()> {
1310 use atproto_identity::key::identify_key;
1312
1313 let known_key = identify_key("did:key:z42tnbHmmnhF11nwSnp5kQJbcZQw2Vbw5WF3ABDSxPtDgU2o")?;
1314 let wrapped_jwk = generate(&known_key)?;
1315
1316 let tp = thumbprint(&wrapped_jwk)?;
1317
1318 assert!(!tp.is_empty());
1320 assert!(tp.len() == 43); let tp2 = thumbprint(&wrapped_jwk)?;
1324 assert_eq!(tp, tp2);
1325
1326 Ok(())
1327 }
1328
1329 #[test]
1330 fn test_thumbprint_performance() -> Result<()> {
1331 use std::time::Instant;
1333
1334 let key = generate_key(KeyType::P256Private)?;
1335 let wrapped_jwk = generate(&key)?;
1336
1337 let start = Instant::now();
1338
1339 for _ in 0..1000 {
1340 let _tp = thumbprint(&wrapped_jwk)?;
1341 }
1342
1343 let duration = start.elapsed();
1344
1345 assert!(
1347 duration.as_millis() < 2000,
1348 "Thumbprint performance test took too long: {:?}",
1349 duration
1350 );
1351
1352 Ok(())
1353 }
1354
1355 #[test]
1356 fn test_thumbprint_spec_compliance() -> Result<()> {
1357 let key = generate_key(KeyType::P256Private)?;
1359 let wrapped_jwk = generate(&key)?;
1360
1361 let tp = thumbprint(&wrapped_jwk)?;
1362
1363 assert_eq!(tp.len(), 43);
1367
1368 for c in tp.chars() {
1370 assert!(c.is_alphanumeric() || c == '-' || c == '_');
1371 }
1372
1373 Ok(())
1374 }
1375
1376 #[test]
1377 fn test_thumbprint_with_all_curves() -> Result<()> {
1378 let test_cases = [
1380 (KeyType::P256Private, "P-256"),
1381 (KeyType::P384Private, "P-384"),
1382 (KeyType::K256Private, "K-256"),
1383 ];
1384
1385 for (key_type, curve_name) in test_cases {
1386 let private_key = generate_key(key_type)?;
1388 let public_key = to_public(&private_key)?;
1389
1390 let private_jwk = generate(&private_key)?;
1391 let public_jwk = generate(&public_key)?;
1392
1393 let private_tp = thumbprint(&private_jwk)?;
1394 let public_tp = thumbprint(&public_jwk)?;
1395
1396 assert_eq!(
1398 private_tp, public_tp,
1399 "Thumbprint mismatch for {}",
1400 curve_name
1401 );
1402
1403 assert_eq!(
1405 private_tp.len(),
1406 43,
1407 "Invalid thumbprint length for {}",
1408 curve_name
1409 );
1410 assert!(
1411 !private_tp.contains('='),
1412 "Thumbprint contains padding for {}",
1413 curve_name
1414 );
1415 }
1416
1417 Ok(())
1418 }
1419
1420 #[test]
1421 fn test_thumbprint_comprehensive() -> Result<()> {
1422 let curves = [
1424 (KeyType::P256Private, "P-256"),
1425 (KeyType::P384Private, "P-384"),
1426 (KeyType::K256Private, "K-256"),
1427 ];
1428
1429 for (key_type, curve_name) in curves {
1430 let keys: Vec<_> = (0..5)
1432 .map(|_| generate_key(key_type.clone()))
1433 .collect::<Result<Vec<_>, _>>()?;
1434
1435 let mut thumbprints = Vec::new();
1436
1437 for (i, key) in keys.iter().enumerate() {
1438 let private_jwk = generate(key)?;
1439 let public_jwk = generate(&to_public(key)?)?;
1440
1441 let private_tp = thumbprint(&private_jwk)?;
1442 let public_tp = thumbprint(&public_jwk)?;
1443
1444 assert_eq!(
1446 private_tp, public_tp,
1447 "Thumbprint mismatch for {} key {}",
1448 curve_name, i
1449 );
1450
1451 assert!(
1453 !thumbprints.contains(&private_tp),
1454 "Duplicate thumbprint for {} key {}",
1455 curve_name,
1456 i
1457 );
1458
1459 thumbprints.push(private_tp);
1460 }
1461
1462 assert_eq!(
1464 thumbprints.len(),
1465 5,
1466 "Not all thumbprints are unique for {}",
1467 curve_name
1468 );
1469
1470 for tp in &thumbprints {
1472 assert_eq!(tp.len(), 43, "Invalid length for {} thumbprint", curve_name);
1473 assert!(
1474 !tp.contains(&['=', '+', '/'][..]),
1475 "Invalid characters in {} thumbprint",
1476 curve_name
1477 );
1478 }
1479 }
1480
1481 Ok(())
1482 }
1483}