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#[derive(Serialize, Deserialize, Clone, PartialEq, Debug)]
20pub struct WrappedJsonWebKey {
21 #[serde(skip_serializing_if = "Option::is_none", default)]
23 pub kid: Option<String>,
24
25 #[serde(skip_serializing_if = "Option::is_none", default)]
27 pub alg: Option<String>,
28
29 #[serde(rename = "use", skip_serializing_if = "Option::is_none")]
31 pub _use: Option<String>,
32
33 #[serde(flatten)]
35 pub jwk: JwkEcKey,
36}
37
38#[derive(Serialize, Deserialize, Clone)]
40pub struct WrappedJsonWebKeySet {
41 pub keys: Vec<WrappedJsonWebKey>,
43}
44
45pub fn generate(key_data: &KeyData) -> Result<WrappedJsonWebKey> {
47 let alg = match key_data.key_type() {
48 KeyType::P256Public => Some("ES256".to_string()),
49 KeyType::P256Private => Some("ES256".to_string()),
50 KeyType::P384Public => Some("ES384".to_string()),
51 KeyType::P384Private => Some("ES384".to_string()),
52 KeyType::K256Public => Some("ES256K".to_string()),
53 KeyType::K256Private => Some("ES256K".to_string()),
54 };
55 let jwk = key_data.try_into()?;
56
57 let public_key = to_public(key_data)?;
58 let kid = Some(public_key.to_string());
59
60 Ok(WrappedJsonWebKey {
61 kid,
62 alg,
63 jwk,
64 _use: Some("sig".to_string()),
65 })
66}
67
68pub fn to_key_data(wrapped_jwk: &WrappedJsonWebKey) -> Result<KeyData, JWKError> {
70 let curve = wrapped_jwk.jwk.crv();
72
73 match curve {
74 "P-256" => {
75 if let Ok(secret_key) = p256::SecretKey::try_from(&wrapped_jwk.jwk) {
77 Ok(KeyData::new(
78 KeyType::P256Private,
79 secret_key.to_bytes().to_vec(),
80 ))
81 } else if let Ok(public_key) = p256::PublicKey::try_from(&wrapped_jwk.jwk) {
82 let compressed = public_key.to_encoded_point(true);
84 Ok(KeyData::new(
85 KeyType::P256Public,
86 compressed.as_bytes().to_vec(),
87 ))
88 } else {
89 Err(JWKError::P256ConversionFailed)
90 }
91 }
92 "P-384" => {
93 if let Ok(secret_key) = p384::SecretKey::try_from(&wrapped_jwk.jwk) {
95 Ok(KeyData::new(
96 KeyType::P384Private,
97 secret_key.to_bytes().to_vec(),
98 ))
99 } else if let Ok(public_key) = p384::PublicKey::try_from(&wrapped_jwk.jwk) {
100 let compressed = public_key.to_encoded_point(true);
102 Ok(KeyData::new(
103 KeyType::P384Public,
104 compressed.as_bytes().to_vec(),
105 ))
106 } else {
107 Err(JWKError::P384ConversionFailed)
108 }
109 }
110 "secp256k1" => {
111 if let Ok(secret_key) = k256::SecretKey::try_from(&wrapped_jwk.jwk) {
113 Ok(KeyData::new(
114 KeyType::K256Private,
115 secret_key.to_bytes().to_vec(),
116 ))
117 } else if let Ok(public_key) = k256::PublicKey::try_from(&wrapped_jwk.jwk) {
118 let compressed = public_key.to_encoded_point(true);
120 Ok(KeyData::new(
121 KeyType::K256Public,
122 compressed.as_bytes().to_vec(),
123 ))
124 } else {
125 Err(JWKError::K256ConversionFailed)
126 }
127 }
128 _ => Err(JWKError::UnsupportedCurve {
129 curve: curve.to_string(),
130 }),
131 }
132}
133
134pub fn thumbprint(wrapped_jwk: &WrappedJsonWebKey) -> Result<String, JWKError> {
145 let jwk_json =
147 serde_json::to_value(&wrapped_jwk.jwk).map_err(|e| JWKError::SerializationError {
148 message: e.to_string(),
149 })?;
150
151 let jwk_obj = jwk_json
153 .as_object()
154 .ok_or_else(|| JWKError::SerializationError {
155 message: "JWK is not a JSON object".to_string(),
156 })?;
157
158 let kty =
160 jwk_obj
161 .get("kty")
162 .and_then(|v| v.as_str())
163 .ok_or_else(|| JWKError::MissingField {
164 field: "kty".to_string(),
165 })?;
166
167 if kty != "EC" {
168 return Err(JWKError::UnsupportedKeyType {
169 kty: kty.to_string(),
170 });
171 }
172
173 let crv = jwk_obj.get("crv").ok_or_else(|| JWKError::MissingField {
175 field: "crv".to_string(),
176 })?;
177 let x = jwk_obj.get("x").ok_or_else(|| JWKError::MissingField {
178 field: "x".to_string(),
179 })?;
180 let y = jwk_obj.get("y").ok_or_else(|| JWKError::MissingField {
181 field: "y".to_string(),
182 })?;
183
184 let thumbprint_json = json!({
186 "crv": crv,
187 "kty": kty,
188 "x": x,
189 "y": y
190 });
191
192 let canonical_json =
194 serde_json::to_string(&thumbprint_json).map_err(|e| JWKError::SerializationError {
195 message: e.to_string(),
196 })?;
197
198 let mut hasher = Sha256::new();
200 hasher.update(canonical_json.as_bytes());
201 let hash = hasher.finalize();
202
203 Ok(URL_SAFE_NO_PAD.encode(hash))
205}
206
207impl TryFrom<WrappedJsonWebKey> for KeyData {
212 type Error = anyhow::Error;
213
214 fn try_from(wrapped_jwk: WrappedJsonWebKey) -> Result<Self, Self::Error> {
215 to_key_data(&wrapped_jwk).map_err(Into::into)
216 }
217}
218
219impl TryFrom<&WrappedJsonWebKey> for KeyData {
224 type Error = anyhow::Error;
225
226 fn try_from(wrapped_jwk: &WrappedJsonWebKey) -> Result<Self, Self::Error> {
227 to_key_data(wrapped_jwk).map_err(Into::into)
228 }
229}
230
231#[cfg(test)]
232mod tests {
233 use super::*;
234 use atproto_identity::key::{generate_key, sign, to_public, validate};
235
236 #[test]
237 fn test_to_key_data_p256_private_round_trip() -> Result<()> {
238 let original_key = generate_key(KeyType::P256Private)?;
240
241 let wrapped_jwk = generate(&original_key)?;
243 assert_eq!(wrapped_jwk.alg, Some("ES256".to_string()));
244 assert_eq!(wrapped_jwk._use, Some("sig".to_string()));
245 assert_eq!(wrapped_jwk.jwk.crv(), "P-256");
246
247 let converted_key = to_key_data(&wrapped_jwk)?;
249
250 assert_eq!(*converted_key.key_type(), KeyType::P256Private);
252 assert_eq!(original_key.bytes(), converted_key.bytes());
253
254 let test_data = "P-256 private key round trip test".as_bytes();
256 let signature = sign(&converted_key, test_data)?;
257 validate(&converted_key, &signature, test_data)?;
258
259 Ok(())
260 }
261
262 #[test]
263 fn test_to_key_data_p256_public_round_trip() -> Result<()> {
264 let private_key = generate_key(KeyType::P256Private)?;
266 let original_public_key = to_public(&private_key)?;
267
268 let wrapped_jwk = generate(&original_public_key)?;
270 assert_eq!(wrapped_jwk.alg, Some("ES256".to_string()));
271 assert_eq!(wrapped_jwk.jwk.crv(), "P-256");
272
273 let converted_key = to_key_data(&wrapped_jwk)?;
275
276 assert_eq!(*converted_key.key_type(), KeyType::P256Public);
278 assert_eq!(original_public_key.bytes(), converted_key.bytes());
279
280 let test_data = "P-256 public key round trip test".as_bytes();
282 let signature = sign(&private_key, test_data)?;
283 validate(&converted_key, &signature, test_data)?;
284
285 Ok(())
286 }
287
288 #[test]
289 fn test_to_key_data_p384_private_round_trip() -> Result<()> {
290 let original_key = generate_key(KeyType::P384Private)?;
292
293 let wrapped_jwk = generate(&original_key)?;
295 assert_eq!(wrapped_jwk.alg, Some("ES384".to_string()));
296 assert_eq!(wrapped_jwk._use, Some("sig".to_string()));
297 assert_eq!(wrapped_jwk.jwk.crv(), "P-384");
298
299 let converted_key = to_key_data(&wrapped_jwk)?;
301
302 assert_eq!(*converted_key.key_type(), KeyType::P384Private);
304 assert_eq!(original_key.bytes(), converted_key.bytes());
305
306 let test_data = "P-384 private key round trip test".as_bytes();
308 let signature = sign(&converted_key, test_data)?;
309 validate(&converted_key, &signature, test_data)?;
310
311 Ok(())
312 }
313
314 #[test]
315 fn test_to_key_data_p384_public_round_trip() -> Result<()> {
316 let private_key = generate_key(KeyType::P384Private)?;
318 let original_public_key = to_public(&private_key)?;
319
320 let wrapped_jwk = generate(&original_public_key)?;
322 assert_eq!(wrapped_jwk.alg, Some("ES384".to_string()));
323 assert_eq!(wrapped_jwk.jwk.crv(), "P-384");
324
325 let converted_key = to_key_data(&wrapped_jwk)?;
327
328 assert_eq!(*converted_key.key_type(), KeyType::P384Public);
330 assert_eq!(original_public_key.bytes(), converted_key.bytes());
331
332 let test_data = "P-384 public key round trip test".as_bytes();
334 let signature = sign(&private_key, test_data)?;
335 validate(&converted_key, &signature, test_data)?;
336
337 Ok(())
338 }
339
340 #[test]
341 fn test_to_key_data_k256_private_round_trip() -> Result<()> {
342 let original_key = generate_key(KeyType::K256Private)?;
344
345 let wrapped_jwk = generate(&original_key)?;
347 assert_eq!(wrapped_jwk.alg, Some("ES256K".to_string()));
348 assert_eq!(wrapped_jwk._use, Some("sig".to_string()));
349 assert_eq!(wrapped_jwk.jwk.crv(), "secp256k1");
350
351 let converted_key = to_key_data(&wrapped_jwk)?;
353
354 assert_eq!(*converted_key.key_type(), KeyType::K256Private);
356 assert_eq!(original_key.bytes(), converted_key.bytes());
357
358 let test_data = "K-256 private key round trip test".as_bytes();
360 let signature = sign(&converted_key, test_data)?;
361 validate(&converted_key, &signature, test_data)?;
362
363 Ok(())
364 }
365
366 #[test]
367 fn test_to_key_data_k256_public_round_trip() -> Result<()> {
368 let private_key = generate_key(KeyType::K256Private)?;
370 let original_public_key = to_public(&private_key)?;
371
372 let wrapped_jwk = generate(&original_public_key)?;
374 assert_eq!(wrapped_jwk.alg, Some("ES256K".to_string()));
375 assert_eq!(wrapped_jwk.jwk.crv(), "secp256k1");
376
377 let converted_key = to_key_data(&wrapped_jwk)?;
379
380 assert_eq!(*converted_key.key_type(), KeyType::K256Public);
382 assert_eq!(original_public_key.bytes(), converted_key.bytes());
383
384 let test_data = "K-256 public key round trip test".as_bytes();
386 let signature = sign(&private_key, test_data)?;
387 validate(&converted_key, &signature, test_data)?;
388
389 Ok(())
390 }
391
392 #[test]
393 fn test_to_key_data_multiple_round_trips() -> Result<()> {
394 for _ in 0..3 {
396 let p256_private = generate_key(KeyType::P256Private)?;
398 let p256_private_jwk = generate(&p256_private)?;
399 let p256_private_converted = to_key_data(&p256_private_jwk)?;
400 assert_eq!(p256_private.bytes(), p256_private_converted.bytes());
401
402 let p256_public = to_public(&p256_private)?;
404 let p256_public_jwk = generate(&p256_public)?;
405 let p256_public_converted = to_key_data(&p256_public_jwk)?;
406 assert_eq!(p256_public.bytes(), p256_public_converted.bytes());
407
408 let p384_private = generate_key(KeyType::P384Private)?;
410 let p384_private_jwk = generate(&p384_private)?;
411 let p384_private_converted = to_key_data(&p384_private_jwk)?;
412 assert_eq!(p384_private.bytes(), p384_private_converted.bytes());
413
414 let p384_public = to_public(&p384_private)?;
416 let p384_public_jwk = generate(&p384_public)?;
417 let p384_public_converted = to_key_data(&p384_public_jwk)?;
418 assert_eq!(p384_public.bytes(), p384_public_converted.bytes());
419
420 let k256_private = generate_key(KeyType::K256Private)?;
422 let k256_private_jwk = generate(&k256_private)?;
423 let k256_private_converted = to_key_data(&k256_private_jwk)?;
424 assert_eq!(k256_private.bytes(), k256_private_converted.bytes());
425
426 let k256_public = to_public(&k256_private)?;
428 let k256_public_jwk = generate(&k256_public)?;
429 let k256_public_converted = to_key_data(&k256_public_jwk)?;
430 assert_eq!(k256_public.bytes(), k256_public_converted.bytes());
431 }
432
433 Ok(())
434 }
435
436 #[test]
437 fn test_to_key_data_cross_curve_verification() -> Result<()> {
438 let p256_private = generate_key(KeyType::P256Private)?;
440 let p384_private = generate_key(KeyType::P384Private)?;
441 let k256_private = generate_key(KeyType::K256Private)?;
442
443 let p256_jwk = generate(&p256_private)?;
445 let p384_jwk = generate(&p384_private)?;
446 let k256_jwk = generate(&k256_private)?;
447
448 let p256_converted = to_key_data(&p256_jwk)?;
449 let p384_converted = to_key_data(&p384_jwk)?;
450 let k256_converted = to_key_data(&k256_jwk)?;
451
452 let test_data = "Cross-curve verification test".as_bytes();
454
455 let p256_signature = sign(&p256_converted, test_data)?;
456 let p384_signature = sign(&p384_converted, test_data)?;
457 let k256_signature = sign(&k256_converted, test_data)?;
458
459 validate(&p256_converted, &p256_signature, test_data)?;
461 validate(&p384_converted, &p384_signature, test_data)?;
462 validate(&k256_converted, &k256_signature, test_data)?;
463
464 assert!(validate(&p256_converted, &p384_signature, test_data).is_err());
466 assert!(validate(&p256_converted, &k256_signature, test_data).is_err());
467 assert!(validate(&p384_converted, &p256_signature, test_data).is_err());
468 assert!(validate(&p384_converted, &k256_signature, test_data).is_err());
469 assert!(validate(&k256_converted, &p256_signature, test_data).is_err());
470 assert!(validate(&k256_converted, &p384_signature, test_data).is_err());
471
472 Ok(())
473 }
474
475 #[test]
476 fn test_to_key_data_algorithm_consistency() -> Result<()> {
477 let p256_key = generate_key(KeyType::P256Private)?;
479 let p384_key = generate_key(KeyType::P384Private)?;
480 let k256_key = generate_key(KeyType::K256Private)?;
481
482 let p256_jwk = generate(&p256_key)?;
483 let p384_jwk = generate(&p384_key)?;
484 let k256_jwk = generate(&k256_key)?;
485
486 assert_eq!(p256_jwk.alg, Some("ES256".to_string()));
488 assert_eq!(p384_jwk.alg, Some("ES384".to_string()));
489 assert_eq!(k256_jwk.alg, Some("ES256K".to_string()));
490
491 assert_eq!(p256_jwk.jwk.crv(), "P-256");
493 assert_eq!(p384_jwk.jwk.crv(), "P-384");
494 assert_eq!(k256_jwk.jwk.crv(), "secp256k1");
495
496 let p256_converted = to_key_data(&p256_jwk)?;
498 let p384_converted = to_key_data(&p384_jwk)?;
499 let k256_converted = to_key_data(&k256_jwk)?;
500
501 assert_eq!(*p256_converted.key_type(), KeyType::P256Private);
502 assert_eq!(*p384_converted.key_type(), KeyType::P384Private);
503 assert_eq!(*k256_converted.key_type(), KeyType::K256Private);
504
505 Ok(())
506 }
507
508 #[test]
509 fn test_to_key_data_key_sizes() -> Result<()> {
510 let p256_private = generate_key(KeyType::P256Private)?;
512 let p384_private = generate_key(KeyType::P384Private)?;
513 let k256_private = generate_key(KeyType::K256Private)?;
514
515 let p256_public = to_public(&p256_private)?;
516 let p384_public = to_public(&p384_private)?;
517 let k256_public = to_public(&k256_private)?;
518
519 let keys = [
521 (&p256_private, 32), (&p384_private, 48), (&k256_private, 32), (&p256_public, 33), (&p384_public, 49), (&k256_public, 33), ];
528
529 for (original_key, expected_size) in keys {
530 let jwk = generate(original_key)?;
531 let converted_key = to_key_data(&jwk)?;
532
533 assert_eq!(
534 converted_key.bytes().len(),
535 expected_size,
536 "Key size mismatch for {:?}",
537 original_key.key_type()
538 );
539 assert_eq!(original_key.bytes(), converted_key.bytes());
540 }
541
542 Ok(())
543 }
544
545 #[test]
546 fn test_to_key_data_did_string_consistency() -> Result<()> {
547 let test_keys = [
549 generate_key(KeyType::P256Private)?,
550 generate_key(KeyType::P384Private)?,
551 generate_key(KeyType::K256Private)?,
552 ];
553
554 for original_key in test_keys {
555 let original_did = format!("{}", original_key);
556
557 let jwk = generate(&original_key)?;
559 let converted_key = to_key_data(&jwk)?;
560 let converted_did = format!("{}", converted_key);
561
562 assert_eq!(
563 original_did,
564 converted_did,
565 "DID string mismatch for {:?}",
566 original_key.key_type()
567 );
568
569 let public_key = to_public(&original_key)?;
571 let public_did = format!("{}", public_key);
572
573 let public_jwk = generate(&public_key)?;
574 let converted_public_key = to_key_data(&public_jwk)?;
575 let converted_public_did = format!("{}", converted_public_key);
576
577 assert_eq!(
578 public_did,
579 converted_public_did,
580 "Public DID string mismatch for {:?}",
581 public_key.key_type()
582 );
583 }
584
585 Ok(())
586 }
587
588 #[test]
589 fn test_to_key_data_unsupported_curve() {
590 let valid_key = generate_key(KeyType::P256Private).unwrap();
598 let valid_jwk = generate(&valid_key).unwrap();
599
600 let result = to_key_data(&valid_jwk);
602 assert!(result.is_ok());
603
604 }
608
609 #[test]
610 fn test_to_key_data_invalid_jwk_conversion() {
611 use serde_json::json;
616
617 let invalid_jwk_json = json!({
619 "kty": "EC",
620 "crv": "P-256",
621 "x": "invalid-base64-data!!!",
622 "y": "also-invalid-base64!!!"
623 });
624
625 let _jwk_result: Result<elliptic_curve::JwkEcKey, _> =
627 serde_json::from_value(invalid_jwk_json);
628 let p256_key = generate_key(KeyType::P256Private).unwrap();
633 let valid_jwk = generate(&p256_key).unwrap();
634
635 let result = to_key_data(&valid_jwk);
637 assert!(result.is_ok());
638 }
639
640 #[test]
641 fn test_to_key_data_round_trip_with_existing_keys() -> Result<()> {
642 use atproto_identity::key::identify_key;
644
645 let test_keys = [
646 "did:key:z42tnbHmmnhF11nwSnp5kQJbcZQw2Vbw5WF3ABDSxPtDgU2o", "did:key:zDnaeXduWbJ1b1Kgjf3uCdCpMDF1LEDizUiyxAxGwerou3Nh2", "did:key:z3vLY4nbXy2rV4Qr65gUtfnSF3A8Be7gmYzUiCX6eo2PR1Rt", "did:key:zQ3shNzMp4oaaQ1gQRzCxMGXFrSW3NEM1M9T6KCY9eA7HhyEA", ];
651
652 for key_did in test_keys {
653 let original_key = identify_key(key_did)?;
654 let jwk = generate(&original_key)?;
655 let converted_key = to_key_data(&jwk)?;
656
657 assert_eq!(*original_key.key_type(), *converted_key.key_type());
659 assert_eq!(original_key.bytes(), converted_key.bytes());
660
661 let original_did = format!("{}", original_key);
663 let converted_did = format!("{}", converted_key);
664 assert_eq!(original_did, converted_did);
665 }
666
667 Ok(())
668 }
669
670 #[test]
671 fn test_to_key_data_metadata_preservation() -> Result<()> {
672 let test_keys = [
674 (generate_key(KeyType::P256Private)?, "ES256", "P-256"),
675 (generate_key(KeyType::P384Private)?, "ES384", "P-384"),
676 (generate_key(KeyType::K256Private)?, "ES256K", "secp256k1"),
677 ];
678
679 for (key, expected_alg, expected_crv) in test_keys {
680 let jwk = generate(&key)?;
681
682 assert_eq!(jwk.alg, Some(expected_alg.to_string()));
684 assert_eq!(jwk._use, Some("sig".to_string()));
685 assert_eq!(jwk.jwk.crv(), expected_crv);
686 assert!(jwk.kid.is_some());
687
688 let converted_key = to_key_data(&jwk)?;
690 assert_eq!(key.bytes(), converted_key.bytes());
691 }
692
693 Ok(())
694 }
695
696 #[test]
697 fn test_to_key_data_performance_stress() -> Result<()> {
698 use std::time::Instant;
700
701 let start = Instant::now();
702
703 for _ in 0..100 {
704 let p256_key = generate_key(KeyType::P256Private)?;
706 let p256_jwk = generate(&p256_key)?;
707 let p256_converted = to_key_data(&p256_jwk)?;
708 assert_eq!(p256_key.bytes(), p256_converted.bytes());
709
710 let p384_key = generate_key(KeyType::P384Private)?;
712 let p384_jwk = generate(&p384_key)?;
713 let p384_converted = to_key_data(&p384_jwk)?;
714 assert_eq!(p384_key.bytes(), p384_converted.bytes());
715
716 let k256_key = generate_key(KeyType::K256Private)?;
718 let k256_jwk = generate(&k256_key)?;
719 let k256_converted = to_key_data(&k256_jwk)?;
720 assert_eq!(k256_key.bytes(), k256_converted.bytes());
721 }
722
723 let duration = start.elapsed();
724 println!("300 round-trip conversions completed in: {:?}", duration);
725
726 assert!(
728 duration.as_millis() < 5000,
729 "Performance test took too long: {:?}",
730 duration
731 );
732
733 Ok(())
734 }
735
736 #[test]
737 fn test_to_key_data_serialization_consistency() -> Result<()> {
738 let test_keys = [
740 generate_key(KeyType::P256Private)?,
741 generate_key(KeyType::P384Private)?,
742 generate_key(KeyType::K256Private)?,
743 ];
744
745 for original_key in test_keys {
746 let jwk = generate(&original_key)?;
748
749 let json_string = serde_json::to_string(&jwk)?;
751 let deserialized_jwk: WrappedJsonWebKey = serde_json::from_str(&json_string)?;
752
753 let converted_from_original = to_key_data(&jwk)?;
755 let converted_from_deserialized = to_key_data(&deserialized_jwk)?;
756
757 assert_eq!(
759 *converted_from_original.key_type(),
760 *converted_from_deserialized.key_type()
761 );
762 assert_eq!(
763 converted_from_original.bytes(),
764 converted_from_deserialized.bytes()
765 );
766 assert_eq!(original_key.bytes(), converted_from_original.bytes());
767 }
768
769 Ok(())
770 }
771
772 #[test]
773 fn test_to_key_data_comprehensive_workflow() -> Result<()> {
774 println!("\n=== WrappedJsonWebKey to KeyData Comprehensive Test ===");
775
776 let test_cases = [
778 ("P-256 private", KeyType::P256Private),
779 ("P-384 private", KeyType::P384Private),
780 ("K-256 private", KeyType::K256Private),
781 ];
782
783 for (description, key_type) in test_cases {
784 println!("Testing {}", description);
785
786 let original_private = generate_key(key_type)?;
788 let original_public = to_public(&original_private)?;
789
790 let private_jwk = generate(&original_private)?;
792 let public_jwk = generate(&original_public)?;
793
794 let converted_private = to_key_data(&private_jwk)?;
796 let converted_public = to_key_data(&public_jwk)?;
797
798 assert_eq!(original_private.bytes(), converted_private.bytes());
800 assert_eq!(original_public.bytes(), converted_public.bytes());
801
802 let test_message = format!("Test data for {}", description);
804 let test_data = test_message.as_bytes();
805
806 let signature_original = sign(&original_private, test_data)?;
807 let signature_converted = sign(&converted_private, test_data)?;
808
809 validate(&original_public, &signature_original, test_data)?;
811 validate(&converted_public, &signature_original, test_data)?;
812 validate(&original_public, &signature_converted, test_data)?;
813 validate(&converted_public, &signature_converted, test_data)?;
814
815 assert_eq!(
817 format!("{}", original_private),
818 format!("{}", converted_private)
819 );
820 assert_eq!(
821 format!("{}", original_public),
822 format!("{}", converted_public)
823 );
824
825 println!(" ✓ {} passed all tests", description);
826 }
827
828 println!("=== All comprehensive tests completed successfully! ===\n");
829
830 Ok(())
831 }
832
833 #[test]
836 fn test_try_from_owned_p256_private() -> Result<()> {
837 let original_key = generate_key(KeyType::P256Private)?;
838 let wrapped_jwk = generate(&original_key)?;
839
840 let converted_key: KeyData = wrapped_jwk.try_into()?;
842
843 assert_eq!(*converted_key.key_type(), KeyType::P256Private);
844 assert_eq!(original_key.bytes(), converted_key.bytes());
845
846 Ok(())
847 }
848
849 #[test]
850 fn test_try_from_reference_p256_private() -> Result<()> {
851 let original_key = generate_key(KeyType::P256Private)?;
852 let wrapped_jwk = generate(&original_key)?;
853
854 let converted_key: KeyData = (&wrapped_jwk).try_into()?;
856
857 assert_eq!(*converted_key.key_type(), KeyType::P256Private);
858 assert_eq!(original_key.bytes(), converted_key.bytes());
859
860 Ok(())
861 }
862
863 #[test]
864 fn test_try_from_explicit_p256_private() -> Result<()> {
865 let original_key = generate_key(KeyType::P256Private)?;
866 let wrapped_jwk = generate(&original_key)?;
867
868 let converted_owned = KeyData::try_from(wrapped_jwk.clone())?;
870 let converted_ref = KeyData::try_from(&wrapped_jwk)?;
871
872 assert_eq!(*converted_owned.key_type(), KeyType::P256Private);
873 assert_eq!(*converted_ref.key_type(), KeyType::P256Private);
874 assert_eq!(original_key.bytes(), converted_owned.bytes());
875 assert_eq!(original_key.bytes(), converted_ref.bytes());
876 assert_eq!(converted_owned.bytes(), converted_ref.bytes());
877
878 Ok(())
879 }
880
881 #[test]
882 fn test_try_into_vs_to_key_data_consistency() -> Result<()> {
883 let test_keys = [
885 generate_key(KeyType::P256Private)?,
886 generate_key(KeyType::P384Private)?,
887 generate_key(KeyType::K256Private)?,
888 ];
889
890 for original_key in test_keys {
891 let public_key = to_public(&original_key)?;
892
893 for key in [&original_key, &public_key] {
894 let wrapped_jwk = generate(key)?;
895
896 let from_to_key_data = to_key_data(&wrapped_jwk)?;
898 let from_try_from_owned: KeyData = wrapped_jwk.clone().try_into()?;
899 let from_try_from_ref: KeyData = (&wrapped_jwk).try_into()?;
900 let from_explicit_owned = KeyData::try_from(wrapped_jwk.clone())?;
901 let from_explicit_ref = KeyData::try_from(&wrapped_jwk)?;
902
903 assert_eq!(from_to_key_data.key_type(), from_try_from_owned.key_type());
905 assert_eq!(from_to_key_data.key_type(), from_try_from_ref.key_type());
906 assert_eq!(from_to_key_data.key_type(), from_explicit_owned.key_type());
907 assert_eq!(from_to_key_data.key_type(), from_explicit_ref.key_type());
908
909 assert_eq!(from_to_key_data.bytes(), from_try_from_owned.bytes());
910 assert_eq!(from_to_key_data.bytes(), from_try_from_ref.bytes());
911 assert_eq!(from_to_key_data.bytes(), from_explicit_owned.bytes());
912 assert_eq!(from_to_key_data.bytes(), from_explicit_ref.bytes());
913 }
914 }
915
916 Ok(())
917 }
918
919 #[test]
920 fn test_trait_implementations_all_curves() -> Result<()> {
921 let test_cases = [
923 (KeyType::P256Private, "P-256 private"),
924 (KeyType::P384Private, "P-384 private"),
925 (KeyType::K256Private, "K-256 private"),
926 ];
927
928 for (key_type, description) in test_cases {
929 let private_key = generate_key(key_type)?;
931 let private_jwk = generate(&private_key)?;
932
933 let converted_private_owned: KeyData = private_jwk.clone().try_into()?;
935 let converted_private_ref: KeyData = (&private_jwk).try_into()?;
936
937 assert_eq!(
938 private_key.bytes(),
939 converted_private_owned.bytes(),
940 "Owned conversion failed for {}",
941 description
942 );
943 assert_eq!(
944 private_key.bytes(),
945 converted_private_ref.bytes(),
946 "Reference conversion failed for {}",
947 description
948 );
949
950 let public_key = to_public(&private_key)?;
952 let public_jwk = generate(&public_key)?;
953
954 let converted_public_owned: KeyData = public_jwk.clone().try_into()?;
956 let converted_public_ref: KeyData = (&public_jwk).try_into()?;
957
958 assert_eq!(
959 public_key.bytes(),
960 converted_public_owned.bytes(),
961 "Public owned conversion failed for {}",
962 description
963 );
964 assert_eq!(
965 public_key.bytes(),
966 converted_public_ref.bytes(),
967 "Public reference conversion failed for {}",
968 description
969 );
970
971 let test_data = format!("Trait test for {}", description);
973 let test_bytes = test_data.as_bytes();
974
975 let signature = sign(&converted_private_owned, test_bytes)?;
976 validate(&converted_public_owned, &signature, test_bytes)?;
977 validate(&converted_public_ref, &signature, test_bytes)?;
978 }
979
980 Ok(())
981 }
982
983 #[test]
984 fn test_trait_error_handling() -> Result<()> {
985 let p256_key = generate_key(KeyType::P256Private)?;
987 let valid_jwk = generate(&p256_key)?;
988
989 let _: KeyData = valid_jwk.clone().try_into()?;
991 let _: KeyData = (&valid_jwk).try_into()?;
992 let _ = KeyData::try_from(valid_jwk.clone())?;
993 let _ = KeyData::try_from(&valid_jwk)?;
994
995 Ok(())
999 }
1000
1001 #[test]
1002 fn test_trait_ownership_semantics() -> Result<()> {
1003 let original_key = generate_key(KeyType::P256Private)?;
1005 let wrapped_jwk = generate(&original_key)?;
1006
1007 let cloned_jwk = wrapped_jwk.clone();
1009 let converted_owned: KeyData = cloned_jwk.try_into()?;
1010
1011 let converted_ref: KeyData = (&wrapped_jwk).try_into()?;
1013
1014 let converted_ref2: KeyData = (&wrapped_jwk).try_into()?;
1016
1017 assert_eq!(converted_owned.bytes(), converted_ref.bytes());
1019 assert_eq!(converted_ref.bytes(), converted_ref2.bytes());
1020 assert_eq!(original_key.bytes(), converted_owned.bytes());
1021
1022 Ok(())
1023 }
1024
1025 #[test]
1026 fn test_trait_type_inference() -> Result<()> {
1027 let original_key = generate_key(KeyType::K256Private)?;
1029 let wrapped_jwk = generate(&original_key)?;
1030
1031 let converted1 = KeyData::try_from(wrapped_jwk.clone())?;
1033 let converted2 = KeyData::try_from(&wrapped_jwk)?;
1034
1035 let converted3: Result<KeyData, _> = wrapped_jwk.clone().try_into();
1037 let converted3 = converted3?;
1038
1039 let converted4: Result<KeyData, _> = (&wrapped_jwk).try_into();
1040 let converted4 = converted4?;
1041
1042 assert_eq!(converted1.bytes(), converted2.bytes());
1044 assert_eq!(converted2.bytes(), converted3.bytes());
1045 assert_eq!(converted3.bytes(), converted4.bytes());
1046 assert_eq!(original_key.bytes(), converted1.bytes());
1047
1048 Ok(())
1049 }
1050
1051 #[test]
1052 fn test_trait_comprehensive_workflow() -> Result<()> {
1053 println!("\n=== TryFrom/TryInto Trait Implementation Test ===");
1054
1055 let test_cases = [
1057 ("P-256", KeyType::P256Private),
1058 ("P-384", KeyType::P384Private),
1059 ("K-256", KeyType::K256Private),
1060 ];
1061
1062 for (curve_name, key_type) in test_cases {
1063 println!("Testing {} trait implementations", curve_name);
1064
1065 let original_private = generate_key(key_type)?;
1067 let original_public = to_public(&original_private)?;
1068
1069 let private_jwk = generate(&original_private)?;
1071 let public_jwk = generate(&original_public)?;
1072
1073 println!(" Testing TryFrom<WrappedJsonWebKey>");
1075 let private_from_owned = KeyData::try_from(private_jwk.clone())?;
1076 let public_from_owned = KeyData::try_from(public_jwk.clone())?;
1077
1078 println!(" Testing TryFrom<&WrappedJsonWebKey>");
1079 let private_from_ref = KeyData::try_from(&private_jwk)?;
1080 let public_from_ref = KeyData::try_from(&public_jwk)?;
1081
1082 println!(" Testing TryInto<KeyData> for WrappedJsonWebKey");
1083 let private_into_owned: KeyData = private_jwk.clone().try_into()?;
1084 let public_into_owned: KeyData = public_jwk.clone().try_into()?;
1085
1086 println!(" Testing TryInto<KeyData> for &WrappedJsonWebKey");
1087 let private_into_ref: KeyData = (&private_jwk).try_into()?;
1088 let public_into_ref: KeyData = (&public_jwk).try_into()?;
1089
1090 let private_results = [
1092 &private_from_owned,
1093 &private_from_ref,
1094 &private_into_owned,
1095 &private_into_ref,
1096 ];
1097 let public_results = [
1098 &public_from_owned,
1099 &public_from_ref,
1100 &public_into_owned,
1101 &public_into_ref,
1102 ];
1103
1104 for result in &private_results[1..] {
1105 assert_eq!(private_results[0].bytes(), result.bytes());
1106 assert_eq!(private_results[0].key_type(), result.key_type());
1107 }
1108
1109 for result in &public_results[1..] {
1110 assert_eq!(public_results[0].bytes(), result.bytes());
1111 assert_eq!(public_results[0].key_type(), result.key_type());
1112 }
1113
1114 assert_eq!(original_private.bytes(), private_results[0].bytes());
1116 assert_eq!(original_public.bytes(), public_results[0].bytes());
1117
1118 let test_data = format!("{} trait test", curve_name);
1120 let test_bytes = test_data.as_bytes();
1121
1122 let signature = sign(&private_from_owned, test_bytes)?;
1123 validate(&public_from_owned, &signature, test_bytes)?;
1124 validate(&public_into_ref, &signature, test_bytes)?;
1125
1126 println!(" ✓ {} trait implementations passed all tests", curve_name);
1127 }
1128
1129 println!("=== All trait implementation tests completed successfully! ===\n");
1130
1131 Ok(())
1132 }
1133
1134 #[test]
1135 fn test_trait_usage_examples() -> Result<()> {
1136 let original_key = generate_key(KeyType::P256Private)?;
1138 let wrapped_jwk = generate(&original_key)?;
1139
1140 let converted1: KeyData = wrapped_jwk.clone().try_into()?;
1142
1143 let converted2: KeyData = (&wrapped_jwk).try_into()?;
1145
1146 let converted3 = KeyData::try_from(wrapped_jwk.clone())?;
1148 let converted4 = KeyData::try_from(&wrapped_jwk)?;
1149
1150 let converted5 = to_key_data(&wrapped_jwk)?;
1152
1153 let results = [
1155 &converted1,
1156 &converted2,
1157 &converted3,
1158 &converted4,
1159 &converted5,
1160 ];
1161 for result in &results[1..] {
1162 assert_eq!(converted1.bytes(), result.bytes());
1163 assert_eq!(converted1.key_type(), result.key_type());
1164 }
1165
1166 assert_eq!(original_key.bytes(), converted1.bytes());
1168 assert_eq!(*original_key.key_type(), *converted1.key_type());
1169
1170 println!("✓ All trait usage examples work correctly");
1171 Ok(())
1172 }
1173
1174 #[test]
1177 fn test_thumbprint_p256() -> Result<()> {
1178 let key = generate_key(KeyType::P256Private)?;
1179 let wrapped_jwk = generate(&key)?;
1180
1181 let tp = thumbprint(&wrapped_jwk)?;
1182
1183 assert!(!tp.is_empty());
1185 assert!(tp.len() > 20); assert!(!tp.contains('=')); assert!(!tp.contains('+')); assert!(!tp.contains('/')); Ok(())
1191 }
1192
1193 #[test]
1194 fn test_thumbprint_p384() -> Result<()> {
1195 let key = generate_key(KeyType::P384Private)?;
1196 let wrapped_jwk = generate(&key)?;
1197
1198 let tp = thumbprint(&wrapped_jwk)?;
1199
1200 assert!(!tp.is_empty());
1202 assert!(tp.len() > 20);
1203 assert!(!tp.contains('='));
1204 assert!(!tp.contains('+'));
1205 assert!(!tp.contains('/'));
1206
1207 Ok(())
1208 }
1209
1210 #[test]
1211 fn test_thumbprint_k256() -> Result<()> {
1212 let key = generate_key(KeyType::K256Private)?;
1213 let wrapped_jwk = generate(&key)?;
1214
1215 let tp = thumbprint(&wrapped_jwk)?;
1216
1217 assert!(!tp.is_empty());
1219 assert!(tp.len() > 20);
1220 assert!(!tp.contains('='));
1221 assert!(!tp.contains('+'));
1222 assert!(!tp.contains('/'));
1223
1224 Ok(())
1225 }
1226
1227 #[test]
1228 fn test_thumbprint_consistency() -> Result<()> {
1229 let key = generate_key(KeyType::P256Private)?;
1231 let wrapped_jwk = generate(&key)?;
1232
1233 let tp1 = thumbprint(&wrapped_jwk)?;
1234 let tp2 = thumbprint(&wrapped_jwk)?;
1235 let tp3 = thumbprint(&wrapped_jwk)?;
1236
1237 assert_eq!(tp1, tp2);
1238 assert_eq!(tp2, tp3);
1239
1240 Ok(())
1241 }
1242
1243 #[test]
1244 fn test_thumbprint_different_keys_different_thumbprints() -> Result<()> {
1245 let key1 = generate_key(KeyType::P256Private)?;
1247 let key2 = generate_key(KeyType::P256Private)?;
1248
1249 let jwk1 = generate(&key1)?;
1250 let jwk2 = generate(&key2)?;
1251
1252 let tp1 = thumbprint(&jwk1)?;
1253 let tp2 = thumbprint(&jwk2)?;
1254
1255 assert_ne!(tp1, tp2);
1256
1257 Ok(())
1258 }
1259
1260 #[test]
1261 fn test_thumbprint_private_vs_public_same_thumbprint() -> Result<()> {
1262 let private_key = generate_key(KeyType::P256Private)?;
1265 let public_key = to_public(&private_key)?;
1266
1267 let private_jwk = generate(&private_key)?;
1268 let public_jwk = generate(&public_key)?;
1269
1270 let private_tp = thumbprint(&private_jwk)?;
1271 let public_tp = thumbprint(&public_jwk)?;
1272
1273 assert_eq!(private_tp, public_tp);
1274
1275 Ok(())
1276 }
1277
1278 #[test]
1279 fn test_thumbprint_cross_curve_different() -> Result<()> {
1280 let p256_key = generate_key(KeyType::P256Private)?;
1282 let p384_key = generate_key(KeyType::P384Private)?;
1283 let k256_key = generate_key(KeyType::K256Private)?;
1284
1285 let p256_jwk = generate(&p256_key)?;
1286 let p384_jwk = generate(&p384_key)?;
1287 let k256_jwk = generate(&k256_key)?;
1288
1289 let p256_tp = thumbprint(&p256_jwk)?;
1290 let p384_tp = thumbprint(&p384_jwk)?;
1291 let k256_tp = thumbprint(&k256_jwk)?;
1292
1293 assert_ne!(p256_tp, p384_tp);
1294 assert_ne!(p256_tp, k256_tp);
1295 assert_ne!(p384_tp, k256_tp);
1296
1297 Ok(())
1298 }
1299
1300 #[test]
1301 fn test_thumbprint_deterministic() -> Result<()> {
1302 use atproto_identity::key::identify_key;
1304
1305 let known_key = identify_key("did:key:z42tnbHmmnhF11nwSnp5kQJbcZQw2Vbw5WF3ABDSxPtDgU2o")?;
1306 let wrapped_jwk = generate(&known_key)?;
1307
1308 let tp = thumbprint(&wrapped_jwk)?;
1309
1310 assert!(!tp.is_empty());
1312 assert!(tp.len() == 43); let tp2 = thumbprint(&wrapped_jwk)?;
1316 assert_eq!(tp, tp2);
1317
1318 Ok(())
1319 }
1320
1321 #[test]
1322 fn test_thumbprint_performance() -> Result<()> {
1323 use std::time::Instant;
1325
1326 let key = generate_key(KeyType::P256Private)?;
1327 let wrapped_jwk = generate(&key)?;
1328
1329 let start = Instant::now();
1330
1331 for _ in 0..1000 {
1332 let _tp = thumbprint(&wrapped_jwk)?;
1333 }
1334
1335 let duration = start.elapsed();
1336
1337 assert!(
1339 duration.as_millis() < 2000,
1340 "Thumbprint performance test took too long: {:?}",
1341 duration
1342 );
1343
1344 Ok(())
1345 }
1346
1347 #[test]
1348 fn test_thumbprint_spec_compliance() -> Result<()> {
1349 let key = generate_key(KeyType::P256Private)?;
1351 let wrapped_jwk = generate(&key)?;
1352
1353 let tp = thumbprint(&wrapped_jwk)?;
1354
1355 assert_eq!(tp.len(), 43);
1359
1360 for c in tp.chars() {
1362 assert!(c.is_alphanumeric() || c == '-' || c == '_');
1363 }
1364
1365 Ok(())
1366 }
1367
1368 #[test]
1369 fn test_thumbprint_with_all_curves() -> Result<()> {
1370 let test_cases = [
1372 (KeyType::P256Private, "P-256"),
1373 (KeyType::P384Private, "P-384"),
1374 (KeyType::K256Private, "K-256"),
1375 ];
1376
1377 for (key_type, curve_name) in test_cases {
1378 let private_key = generate_key(key_type)?;
1380 let public_key = to_public(&private_key)?;
1381
1382 let private_jwk = generate(&private_key)?;
1383 let public_jwk = generate(&public_key)?;
1384
1385 let private_tp = thumbprint(&private_jwk)?;
1386 let public_tp = thumbprint(&public_jwk)?;
1387
1388 assert_eq!(
1390 private_tp, public_tp,
1391 "Thumbprint mismatch for {}",
1392 curve_name
1393 );
1394
1395 assert_eq!(
1397 private_tp.len(),
1398 43,
1399 "Invalid thumbprint length for {}",
1400 curve_name
1401 );
1402 assert!(
1403 !private_tp.contains('='),
1404 "Thumbprint contains padding for {}",
1405 curve_name
1406 );
1407 }
1408
1409 Ok(())
1410 }
1411
1412 #[test]
1413 fn test_thumbprint_comprehensive() -> Result<()> {
1414 let curves = [
1416 (KeyType::P256Private, "P-256"),
1417 (KeyType::P384Private, "P-384"),
1418 (KeyType::K256Private, "K-256"),
1419 ];
1420
1421 for (key_type, curve_name) in curves {
1422 let keys: Vec<_> = (0..5)
1424 .map(|_| generate_key(key_type.clone()))
1425 .collect::<Result<Vec<_>, _>>()?;
1426
1427 let mut thumbprints = Vec::new();
1428
1429 for (i, key) in keys.iter().enumerate() {
1430 let private_jwk = generate(key)?;
1431 let public_jwk = generate(&to_public(key)?)?;
1432
1433 let private_tp = thumbprint(&private_jwk)?;
1434 let public_tp = thumbprint(&public_jwk)?;
1435
1436 assert_eq!(
1438 private_tp, public_tp,
1439 "Thumbprint mismatch for {} key {}",
1440 curve_name, i
1441 );
1442
1443 assert!(
1445 !thumbprints.contains(&private_tp),
1446 "Duplicate thumbprint for {} key {}",
1447 curve_name,
1448 i
1449 );
1450
1451 thumbprints.push(private_tp);
1452 }
1453
1454 assert_eq!(
1456 thumbprints.len(),
1457 5,
1458 "Not all thumbprints are unique for {}",
1459 curve_name
1460 );
1461
1462 for tp in &thumbprints {
1464 assert_eq!(tp.len(), 43, "Invalid length for {} thumbprint", curve_name);
1465 assert!(
1466 !tp.contains(&['=', '+', '/'][..]),
1467 "Invalid characters in {} thumbprint",
1468 curve_name
1469 );
1470 }
1471 }
1472
1473 Ok(())
1474 }
1475}