A library for ATProtocol identities.
1//! Cryptographic key operations for AT Protocol identity.
2//!
3//! Elliptic curve cryptography for P-256, P-384, and K-256 curves including
4//! key identification, signature validation, and content signing.
5//! - **P-384** (secp384r1/ES384): NIST standard curve, providing higher security than P-256
6//! - **K-256** (secp256k1/ES256K): Bitcoin curve, widely used in blockchain applications
7//!
8//! # Key Operations
9//!
10//! - Key type identification from multibase-encoded DID key strings
11//! - ECDSA signature validation for both public and private keys
12//! - Content signing with private keys
13//! - Cryptographic key generation for private keys
14//! - Public key derivation from private keys
15//! - DID key method prefix handling
16//!
17//! # Example
18//!
19//! ```rust
20//! use atproto_identity::key::{identify_key, generate_key, to_public, validate, sign, KeyType, KeyData};
21//! use elliptic_curve::JwkEcKey;
22//!
23//! fn main() -> Result<(), Box<dyn std::error::Error>> {
24//! // Identify existing keys
25//! let key_data = identify_key("did:key:zQ3shNzMp4oaaQ1gQRzCxMGXFrSW3NEM1M9T6KCY9eA7HhyEA")?;
26//! assert_eq!(*key_data.key_type(), KeyType::K256Public);
27//!
28//! // Generate new private keys (P-256, P-384, or K-256)
29//! let p256_key = generate_key(KeyType::P256Private)?;
30//! let p384_key = generate_key(KeyType::P384Private)?;
31//! let k256_key = generate_key(KeyType::K256Private)?;
32//!
33//! // Derive public key from private key
34//! let p384_public = to_public(&p384_key)?;
35//! assert_eq!(*p384_public.key_type(), KeyType::P384Public);
36//!
37//! // Sign and verify with derived keys
38//! let message = b"Hello AT Protocol!";
39//! let signature = sign(&p384_key, message)?;
40//! validate(&p384_public, &signature, message)?;
41//!
42//! // Convert to JWK format (P-256 and P-384 support JWK)
43//! let p256_key_data = identify_key("did:key:zDnaeXduWbJ1b1Kgjf3uCdCpMDF1LEDizUiyxAxGwerou3Nh2")?;
44//! let p256_jwk: JwkEcKey = (&p256_key_data).try_into()?;
45//! let p384_jwk: JwkEcKey = (&p384_key).try_into()?;
46//! Ok(())
47//! }
48//! ```
49
50use anyhow::{Context, Result, anyhow};
51use ecdsa::signature::Signer;
52use elliptic_curve::JwkEcKey;
53use elliptic_curve::sec1::ToEncodedPoint;
54
55use crate::model::VerificationMethod;
56use crate::traits::IdentityResolver;
57
58pub use crate::traits::KeyResolver;
59use std::sync::Arc;
60
61use crate::errors::KeyError;
62
63#[cfg(feature = "zeroize")]
64use zeroize::{Zeroize, ZeroizeOnDrop};
65
66/// Cryptographic key types supported for AT Protocol identity.
67#[derive(Clone, PartialEq, Debug)]
68#[cfg_attr(feature = "zeroize", derive(Zeroize, ZeroizeOnDrop))]
69pub enum KeyType {
70 /// A p256 (P-256 / secp256r1 / ES256) public key.
71 /// The multibase / multicodec prefix is 8024.
72 P256Public,
73
74 /// A p256 (P-256 / secp256r1 / ES256) private key.
75 /// The multibase / multicodec prefix is 8626.
76 P256Private,
77
78 /// A p384 (P-384 / secp384r1 / ES384) public key.
79 /// The multibase / multicodec prefix is 1200.
80 P384Public,
81
82 /// A p384 (P-384 / secp384r1 / ES384) private key.
83 /// The multibase / multicodec prefix is 1301.
84 P384Private,
85
86 /// A k256 (K-256 / secp256k1 / ES256K) public key.
87 /// The multibase / multicodec prefix is e701.
88 K256Public,
89
90 /// A k256 (K-256 / secp256k1 / ES256K) private key.
91 /// The multibase / multicodec prefix is 8126.
92 K256Private,
93}
94
95impl std::fmt::Display for KeyType {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 match self {
98 KeyType::P256Public => write!(f, "P256Public"),
99 KeyType::P256Private => write!(f, "P256Private"),
100 KeyType::P384Public => write!(f, "P384Public"),
101 KeyType::P384Private => write!(f, "P384Private"),
102 KeyType::K256Public => write!(f, "K256Public"),
103 KeyType::K256Private => write!(f, "K256Private"),
104 }
105 }
106}
107
108/// A wrapper for cryptographic key data containing the key type and raw bytes.
109///
110/// This struct encapsulates the result of key identification and provides methods
111/// for accessing the key type and bytes, as well as conversion to JWK format.
112///
113/// When creating variables for instances of this type, they should have the
114/// suffix `key_data`. Additionally the should have the prefix `public_` or
115/// `private_` to indiciate how they are used. Examples include:
116/// * `public_signing_key_data`
117/// * `private_dpop_key_data`
118///
119#[derive(Clone)]
120#[cfg_attr(feature = "zeroize", derive(zeroize::Zeroize, zeroize::ZeroizeOnDrop))]
121pub struct KeyData(pub KeyType, pub Vec<u8>);
122
123impl KeyData {
124 /// Creates a new KeyData instance.
125 pub fn new(key_type: KeyType, bytes: Vec<u8>) -> Self {
126 KeyData(key_type, bytes)
127 }
128
129 /// Returns the key type.
130 pub fn key_type(&self) -> &KeyType {
131 &self.0
132 }
133
134 /// Returns the raw key bytes.
135 pub fn bytes(&self) -> &[u8] {
136 &self.1
137 }
138
139 /// Consumes self and returns the key type and bytes as a tuple.
140 pub fn into_parts(self) -> (KeyType, Vec<u8>) {
141 (self.0.clone(), self.1.clone())
142 }
143}
144
145impl std::fmt::Display for KeyData {
146 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
147 // Get the multicodec prefix based on key type
148 let prefix = match self.key_type() {
149 KeyType::P256Private => [0x86, 0x26],
150 KeyType::P256Public => [0x80, 0x24],
151 KeyType::P384Private => [0x13, 0x01],
152 KeyType::P384Public => [0x12, 0x00],
153 KeyType::K256Private => [0x81, 0x26],
154 KeyType::K256Public => [0xe7, 0x01],
155 };
156
157 // Combine prefix and key bytes
158 let mut multicodec_bytes = Vec::with_capacity(2 + self.bytes().len());
159 multicodec_bytes.extend_from_slice(&prefix);
160 multicodec_bytes.extend_from_slice(self.bytes());
161
162 // Encode using multibase (base58btc)
163 let multibase_encoded = multibase::encode(multibase::Base::Base58Btc, &multicodec_bytes);
164
165 // Add DID key prefix
166 write!(f, "did:key:{}", multibase_encoded)
167 }
168}
169
170/// DID key method prefix.
171const DID_METHOD_KEY_PREFIX: &str = "did:key:";
172
173/// Extracts the value portion from a DID key string.
174///
175/// Removes the "did:key:" prefix if present, otherwise returns the original string.
176pub fn did_method_key_value(key: &str) -> &str {
177 match key.strip_prefix(DID_METHOD_KEY_PREFIX) {
178 Some(value) => value,
179 None => key,
180 }
181}
182
183/// Identifies the key type and extracts the key data from a multibase-encoded key.
184///
185/// Returns a KeyData instance containing the key type and the raw key bytes.
186pub fn identify_key(key: &str) -> Result<KeyData, KeyError> {
187 let stripped_key = did_method_key_value(key);
188 let (_, decoded_multibase_key) =
189 multibase::decode(stripped_key).map_err(|error| KeyError::DecodeError { error })?;
190
191 if decoded_multibase_key.len() < 3 {
192 return Err(KeyError::UnidentifiedKeyType);
193 }
194
195 // These values were verified using the following method:
196 //
197 // 1. Use goat to generate p256 and k256 keys to sample.
198 // `goat key generate -t k256`
199 //
200 // 2. Use `multibase` and `xxd` to view the hex output
201 // `multibase decode zQ3shj41kYrAKpgMvWFZ8L4uFhQ6P57zpiQEuvL1LWWa8sZqN | xxd`
202 //
203 // See also: https://github.com/bluesky-social/indigo/tree/main/cmd/goat
204 // See also: https://github.com/docknetwork/multibase-cli
205
206 match &decoded_multibase_key[..2] {
207 // P-256 / secp256r1 / ES256 private key
208 [0x86, 0x26] => Ok(KeyData::new(
209 KeyType::P256Private,
210 decoded_multibase_key[2..].to_vec(),
211 )),
212
213 // P-256 / secp256r1 / ES256 public key
214 [0x80, 0x24] => Ok(KeyData::new(
215 KeyType::P256Public,
216 decoded_multibase_key[2..].to_vec(),
217 )),
218
219 // P-384 / secp384r1 / ES384 private key
220 [0x13, 0x01] => Ok(KeyData::new(
221 KeyType::P384Private,
222 decoded_multibase_key[2..].to_vec(),
223 )),
224
225 // P-384 / secp384r1 / ES384 public key
226 [0x12, 0x00] => Ok(KeyData::new(
227 KeyType::P384Public,
228 decoded_multibase_key[2..].to_vec(),
229 )),
230
231 // K-256 / secp256k1 / ES256K private key
232 [0x81, 0x26] => Ok(KeyData::new(
233 KeyType::K256Private,
234 decoded_multibase_key[2..].to_vec(),
235 )),
236
237 // K-256 / secp256k1 / ES256K public key
238 [0xe7, 0x01] => Ok(KeyData::new(
239 KeyType::K256Public,
240 decoded_multibase_key[2..].to_vec(),
241 )),
242
243 _ => Err(KeyError::InvalidMultibaseKeyType {
244 prefix: decoded_multibase_key[..2].to_vec(),
245 }),
246 }
247}
248
249/// Validates a signature against content using the provided key.
250///
251/// Supports both public and private keys for signature verification.
252pub fn validate(key_data: &KeyData, signature: &[u8], content: &[u8]) -> Result<(), KeyError> {
253 match *key_data.key_type() {
254 KeyType::P256Public => {
255 let signature = ecdsa::Signature::from_slice(signature)
256 .map_err(|error| KeyError::SignatureError { error })?;
257 let verifying_key = p256::ecdsa::VerifyingKey::from_sec1_bytes(key_data.bytes())
258 .map_err(|error| KeyError::P256Error { error })?;
259 ecdsa::signature::Verifier::verify(&verifying_key, content, &signature)
260 .map_err(|error| KeyError::ECDSAError { error })
261 }
262 KeyType::P384Public => {
263 let signature = ecdsa::Signature::from_slice(signature)
264 .map_err(|error| KeyError::SignatureError { error })?;
265 let verifying_key = p384::ecdsa::VerifyingKey::from_sec1_bytes(key_data.bytes())
266 .map_err(|error| KeyError::P384Error { error })?;
267 ecdsa::signature::Verifier::verify(&verifying_key, content, &signature)
268 .map_err(|error| KeyError::ECDSAError { error })
269 }
270 KeyType::K256Public => {
271 let signature = ecdsa::Signature::from_slice(signature)
272 .map_err(|error| KeyError::SignatureError { error })?;
273 let verifying_key = k256::ecdsa::VerifyingKey::from_sec1_bytes(key_data.bytes())
274 .map_err(|error| KeyError::K256Error { error })?;
275 ecdsa::signature::Verifier::verify(&verifying_key, content, &signature)
276 .map_err(|error| KeyError::ECDSAError { error })
277 }
278 KeyType::P256Private => {
279 let signature = ecdsa::Signature::from_slice(signature)
280 .map_err(|error| KeyError::SignatureError { error })?;
281 let secret_key: p256::SecretKey =
282 ecdsa::elliptic_curve::SecretKey::from_slice(key_data.bytes())
283 .map_err(|error| KeyError::SecretKeyError { error })?;
284 let public_key = secret_key.public_key();
285 let verifying_key = p256::ecdsa::VerifyingKey::from(public_key);
286 ecdsa::signature::Verifier::verify(&verifying_key, content, &signature)
287 .map_err(|error| KeyError::ECDSAError { error })
288 }
289 KeyType::P384Private => {
290 let signature = ecdsa::Signature::from_slice(signature)
291 .map_err(|error| KeyError::SignatureError { error })?;
292 let secret_key: p384::SecretKey =
293 ecdsa::elliptic_curve::SecretKey::from_slice(key_data.bytes())
294 .map_err(|error| KeyError::SecretKeyError { error })?;
295 let public_key = secret_key.public_key();
296 let verifying_key = p384::ecdsa::VerifyingKey::from(public_key);
297 ecdsa::signature::Verifier::verify(&verifying_key, content, &signature)
298 .map_err(|error| KeyError::ECDSAError { error })
299 }
300 KeyType::K256Private => {
301 let signature = ecdsa::Signature::from_slice(signature)
302 .map_err(|error| KeyError::SignatureError { error })?;
303 let secret_key: k256::SecretKey =
304 ecdsa::elliptic_curve::SecretKey::from_slice(key_data.bytes())
305 .map_err(|error| KeyError::SecretKeyError { error })?;
306 let public_key = secret_key.public_key();
307 let verifying_key = k256::ecdsa::VerifyingKey::from(public_key);
308 ecdsa::signature::Verifier::verify(&verifying_key, content, &signature)
309 .map_err(|error| KeyError::ECDSAError { error })
310 }
311 }
312}
313
314/// Signs content using a private key.
315///
316/// Returns an error if a public key is provided instead of a private key.
317pub fn sign(key_data: &KeyData, content: &[u8]) -> Result<Vec<u8>, KeyError> {
318 match *key_data.key_type() {
319 KeyType::K256Public | KeyType::P256Public | KeyType::P384Public => {
320 Err(KeyError::PrivateKeyRequiredForSignature)
321 }
322 KeyType::P256Private => {
323 let secret_key: p256::SecretKey =
324 ecdsa::elliptic_curve::SecretKey::from_slice(key_data.bytes())
325 .map_err(|error| KeyError::SecretKeyError { error })?;
326 let signing_key: p256::ecdsa::SigningKey = p256::ecdsa::SigningKey::from(secret_key);
327 let signature: p256::ecdsa::Signature = signing_key
328 .try_sign(content)
329 .map_err(|error| KeyError::ECDSAError { error })?;
330 Ok(signature.to_vec())
331 }
332 KeyType::P384Private => {
333 let secret_key: p384::SecretKey =
334 ecdsa::elliptic_curve::SecretKey::from_slice(key_data.bytes())
335 .map_err(|error| KeyError::SecretKeyError { error })?;
336 let signing_key: p384::ecdsa::SigningKey = p384::ecdsa::SigningKey::from(secret_key);
337 let signature: p384::ecdsa::Signature = signing_key
338 .try_sign(content)
339 .map_err(|error| KeyError::ECDSAError { error })?;
340 Ok(signature.to_vec())
341 }
342 KeyType::K256Private => {
343 let secret_key: k256::SecretKey =
344 ecdsa::elliptic_curve::SecretKey::from_slice(key_data.bytes())
345 .map_err(|error| KeyError::SecretKeyError { error })?;
346 let signing_key: k256::ecdsa::SigningKey = k256::ecdsa::SigningKey::from(secret_key);
347 let signature: k256::ecdsa::Signature = signing_key
348 .try_sign(content)
349 .map_err(|error| KeyError::ECDSAError { error })?;
350 Ok(signature.to_vec())
351 }
352 }
353}
354
355/// Key resolver implementation that fetches DID documents using an [`IdentityResolver`].
356#[derive(Clone)]
357pub struct IdentityDocumentKeyResolver {
358 identity_resolver: Arc<dyn IdentityResolver>,
359}
360
361impl IdentityDocumentKeyResolver {
362 /// Creates a new key resolver backed by an [`IdentityResolver`].
363 pub fn new(identity_resolver: Arc<dyn IdentityResolver>) -> Self {
364 Self { identity_resolver }
365 }
366}
367
368#[async_trait::async_trait]
369impl KeyResolver for IdentityDocumentKeyResolver {
370 async fn resolve(&self, key: &str) -> Result<KeyData> {
371 if let Some(did_key) = key.split('#').next() {
372 if let Ok(key_data) = identify_key(did_key) {
373 return Ok(key_data);
374 }
375 } else if let Ok(key_data) = identify_key(key) {
376 return Ok(key_data);
377 }
378
379 let (did, fragment) = key
380 .split_once('#')
381 .context("Key reference must contain a DID fragment (e.g., did:example#key)")?;
382
383 if did.is_empty() || fragment.is_empty() {
384 return Err(anyhow!(
385 "Key reference must include both DID and fragment (received `{key}`)"
386 ));
387 }
388
389 let document = self.identity_resolver.resolve(did).await?;
390 let fragment_with_hash = format!("#{fragment}");
391
392 let public_key_multibase = document
393 .verification_method
394 .iter()
395 .find_map(|method| match method {
396 VerificationMethod::Multikey {
397 id,
398 public_key_multibase,
399 ..
400 } if id == key || *id == fragment_with_hash => Some(public_key_multibase.clone()),
401 _ => None,
402 })
403 .context(format!(
404 "Verification method `{key}` not found in DID document `{did}`"
405 ))?;
406
407 let full_key = if public_key_multibase.starts_with("did:key:") {
408 public_key_multibase
409 } else {
410 format!("did:key:{}", public_key_multibase)
411 };
412
413 identify_key(&full_key).context("Failed to parse key data from verification method")
414 }
415}
416
417impl TryInto<JwkEcKey> for &KeyData {
418 type Error = KeyError;
419
420 fn try_into(self) -> Result<JwkEcKey, Self::Error> {
421 match *self.key_type() {
422 KeyType::P256Public => {
423 let public_key = p256::PublicKey::from_sec1_bytes(self.bytes()).map_err(|e| {
424 KeyError::JWKConversionFailed {
425 error: format!("Failed to parse P256 public key: {}", e),
426 }
427 })?;
428 Ok(public_key.to_jwk())
429 }
430 KeyType::P256Private => {
431 let secret_key = p256::SecretKey::from_slice(self.bytes())
432 .map_err(|error| KeyError::SecretKeyError { error })?;
433 Ok(secret_key.to_jwk())
434 }
435 KeyType::P384Public => {
436 let public_key = p384::PublicKey::from_sec1_bytes(self.bytes()).map_err(|e| {
437 KeyError::JWKConversionFailed {
438 error: format!("Failed to parse P384 public key: {}", e),
439 }
440 })?;
441 Ok(public_key.to_jwk())
442 }
443 KeyType::P384Private => {
444 let secret_key = p384::SecretKey::from_slice(self.bytes())
445 .map_err(|error| KeyError::SecretKeyError { error })?;
446 Ok(secret_key.to_jwk())
447 }
448 KeyType::K256Public => {
449 let public_key = k256::PublicKey::from_sec1_bytes(self.bytes()).map_err(|e| {
450 KeyError::JWKConversionFailed {
451 error: format!("Failed to parse k256 public key: {}", e),
452 }
453 })?;
454 Ok(public_key.to_jwk())
455 }
456 KeyType::K256Private => {
457 let secret_key = k256::SecretKey::from_slice(self.bytes())
458 .map_err(|error| KeyError::SecretKeyError { error })?;
459 Ok(secret_key.to_jwk())
460 }
461 }
462 }
463}
464
465/// Generates a new cryptographic key of the specified type.
466///
467/// # Arguments
468/// * `key_type` - The type of key to generate
469///
470/// # Returns
471/// A `KeyData` containing the generated key material
472///
473/// # Errors
474/// * Returns `KeyError::PublicKeyGenerationNotSupported` for public key types
475/// * Returns `KeyError::SecretKeyError` if key generation fails
476///
477/// # Example
478/// ```rust
479/// use atproto_identity::key::{generate_key, KeyType};
480///
481/// let private_key = generate_key(KeyType::P256Private)?;
482/// assert_eq!(*private_key.key_type(), KeyType::P256Private);
483/// # Ok::<(), atproto_identity::errors::KeyError>(())
484/// ```
485pub fn generate_key(key_type: KeyType) -> Result<KeyData, KeyError> {
486 match key_type {
487 KeyType::P256Private => {
488 let secret_key = p256::SecretKey::random(&mut rand::thread_rng());
489 Ok(KeyData::new(
490 KeyType::P256Private,
491 secret_key.to_bytes().to_vec(),
492 ))
493 }
494 KeyType::P384Private => {
495 let secret_key = p384::SecretKey::random(&mut rand::thread_rng());
496 Ok(KeyData::new(
497 KeyType::P384Private,
498 secret_key.to_bytes().to_vec(),
499 ))
500 }
501 KeyType::K256Private => {
502 let secret_key = k256::SecretKey::random(&mut rand::thread_rng());
503 Ok(KeyData::new(
504 KeyType::K256Private,
505 secret_key.to_bytes().to_vec(),
506 ))
507 }
508 KeyType::P256Public => Err(KeyError::PublicKeyGenerationNotSupported),
509 KeyType::P384Public => Err(KeyError::PublicKeyGenerationNotSupported),
510 KeyType::K256Public => Err(KeyError::PublicKeyGenerationNotSupported),
511 }
512}
513
514/// Derives a public key from a private key, or returns the key if it's already public.
515///
516/// # Arguments
517/// * `key_data` - The key data to convert to public key format
518///
519/// # Returns
520/// A `KeyData` containing the corresponding public key
521///
522/// # Errors
523/// * Returns `KeyError::SecretKeyError` if private key parsing fails
524///
525/// # Example
526/// ```rust
527/// use atproto_identity::key::{generate_key, to_public, KeyType};
528///
529/// let private_key = generate_key(KeyType::P256Private)?;
530/// let public_key = to_public(&private_key)?;
531/// assert_eq!(*public_key.key_type(), KeyType::P256Public);
532///
533/// // Works with public keys too
534/// let same_public_key = to_public(&public_key)?;
535/// assert_eq!(public_key.bytes(), same_public_key.bytes());
536/// # Ok::<(), atproto_identity::errors::KeyError>(())
537/// ```
538pub fn to_public(key_data: &KeyData) -> Result<KeyData, KeyError> {
539 match key_data.key_type() {
540 KeyType::P256Private => {
541 let secret_key: p256::SecretKey =
542 ecdsa::elliptic_curve::SecretKey::from_slice(key_data.bytes())
543 .map_err(|error| KeyError::SecretKeyError { error })?;
544 let public_key = secret_key.public_key();
545 let compressed = public_key.to_encoded_point(true);
546 let public_key_bytes = compressed.to_bytes();
547 Ok(KeyData::new(KeyType::P256Public, public_key_bytes.to_vec()))
548 }
549 KeyType::P384Private => {
550 let secret_key: p384::SecretKey =
551 ecdsa::elliptic_curve::SecretKey::from_slice(key_data.bytes())
552 .map_err(|error| KeyError::SecretKeyError { error })?;
553 let public_key = secret_key.public_key();
554 let compressed = public_key.to_encoded_point(true);
555 let public_key_bytes = compressed.to_bytes();
556 Ok(KeyData::new(KeyType::P384Public, public_key_bytes.to_vec()))
557 }
558 KeyType::K256Private => {
559 let secret_key: k256::SecretKey =
560 ecdsa::elliptic_curve::SecretKey::from_slice(key_data.bytes())
561 .map_err(|error| KeyError::SecretKeyError { error })?;
562 let public_key = secret_key.public_key();
563 let public_key_bytes = public_key.to_sec1_bytes();
564 Ok(KeyData::new(KeyType::K256Public, public_key_bytes.to_vec()))
565 }
566 KeyType::P256Public | KeyType::P384Public | KeyType::K256Public => {
567 // Return a clone of the existing public key
568 Ok(key_data.clone())
569 }
570 }
571}
572
573#[cfg(test)]
574mod tests {
575 use super::*;
576
577 #[test]
578 fn test_identify_key() {
579 // Test valid K256 private key (repeat 4 times as in original test)
580 for _ in 0..4 {
581 let result = identify_key("z3vLVqpQveB3w8G6MQsLVseJ1Z2E1JyQzUj6WgRYNNwB9jdE");
582 assert!(result.is_ok());
583 let key_data = result.unwrap();
584 assert_eq!(*key_data.key_type(), KeyType::K256Private);
585 }
586
587 // Test invalid multibase encoding
588 assert!(matches!(
589 identify_key("asdasdasd"),
590 Err(KeyError::DecodeError { .. })
591 ));
592
593 // Test invalid key type prefix
594 assert!(matches!(
595 identify_key("z4vLVqpQveB3w8G6MQsLVseJ1Z2E1JyQzUj6WgRYNNwB9jdE"),
596 Err(KeyError::InvalidMultibaseKeyType { .. })
597 ));
598 }
599
600 #[test]
601 fn test_sign_p256() -> Result<()> {
602 let private_key = "did:key:z42tnbHmmnhF11nwSnp5kQJbcZQw2Vbw5WF3ABDSxPtDgU2o";
603 let public_key = "did:key:zDnaeXduWbJ1b1Kgjf3uCdCpMDF1LEDizUiyxAxGwerou3Nh2";
604
605 let private_key_data = identify_key(private_key);
606 assert!(private_key_data.is_ok());
607 let private_key_data = private_key_data.unwrap();
608 assert_eq!(*private_key_data.key_type(), KeyType::P256Private);
609
610 let public_key_data = identify_key(public_key);
611 assert!(public_key_data.is_ok());
612 let public_key_data = public_key_data.unwrap();
613 assert_eq!(*public_key_data.key_type(), KeyType::P256Public);
614
615 let content = "hello world".as_bytes();
616
617 let signature = sign(&private_key_data, content);
618 assert!(signature.is_ok());
619 let signature = signature.unwrap();
620
621 {
622 let validation = validate(&public_key_data, &signature, content);
623 assert!(validation.is_ok());
624 }
625 {
626 let validation = validate(&private_key_data, &signature, content);
627 assert!(validation.is_ok());
628 }
629 Ok(())
630 }
631
632 #[test]
633 fn test_sign_k256() -> Result<()> {
634 let private_key = "did:key:z3vLY4nbXy2rV4Qr65gUtfnSF3A8Be7gmYzUiCX6eo2PR1Rt";
635 let public_key = "did:key:zQ3shNzMp4oaaQ1gQRzCxMGXFrSW3NEM1M9T6KCY9eA7HhyEA";
636
637 let private_key_data = identify_key(private_key);
638 assert!(private_key_data.is_ok());
639 let private_key_data = private_key_data.unwrap();
640 assert_eq!(*private_key_data.key_type(), KeyType::K256Private);
641
642 let public_key_data = identify_key(public_key);
643 assert!(public_key_data.is_ok());
644 let public_key_data = public_key_data.unwrap();
645 assert_eq!(*public_key_data.key_type(), KeyType::K256Public);
646
647 let content = "hello world".as_bytes();
648
649 let signature = sign(&private_key_data, content);
650 assert!(signature.is_ok());
651 let signature = signature.unwrap();
652
653 {
654 let validation = validate(&public_key_data, &signature, content);
655 assert!(validation.is_ok());
656 }
657 {
658 let validation = validate(&private_key_data, &signature, content);
659 assert!(validation.is_ok());
660 }
661 Ok(())
662 }
663
664 #[test]
665 fn test_to_jwk_p256() -> Result<()> {
666 let private_key = "did:key:z42tnbHmmnhF11nwSnp5kQJbcZQw2Vbw5WF3ABDSxPtDgU2o";
667 let public_key = "did:key:zDnaeXduWbJ1b1Kgjf3uCdCpMDF1LEDizUiyxAxGwerou3Nh2";
668
669 let private_key_data = identify_key(private_key);
670 assert!(private_key_data.is_ok());
671 let private_key_data = private_key_data.unwrap();
672 assert_eq!(*private_key_data.key_type(), KeyType::P256Private);
673
674 let public_key_data = identify_key(public_key);
675 assert!(public_key_data.is_ok());
676 let public_key_data = public_key_data.unwrap();
677 assert_eq!(*public_key_data.key_type(), KeyType::P256Public);
678
679 // Test private key to JWK conversion
680 let private_jwk: Result<elliptic_curve::JwkEcKey, _> = (&private_key_data).try_into();
681 assert!(private_jwk.is_ok());
682
683 // Test public key to JWK conversion
684 let public_jwk: Result<elliptic_curve::JwkEcKey, _> = (&public_key_data).try_into();
685 assert!(public_jwk.is_ok());
686
687 Ok(())
688 }
689
690 #[test]
691 fn test_to_jwk_k256_supported() -> Result<()> {
692 let private_key = "did:key:z3vLY4nbXy2rV4Qr65gUtfnSF3A8Be7gmYzUiCX6eo2PR1Rt";
693 let public_key = "did:key:zQ3shNzMp4oaaQ1gQRzCxMGXFrSW3NEM1M9T6KCY9eA7HhyEA";
694
695 let private_key_data = identify_key(private_key);
696 assert!(private_key_data.is_ok());
697 let private_key_data = private_key_data.unwrap();
698 assert_eq!(*private_key_data.key_type(), KeyType::K256Private);
699
700 let public_key_data = identify_key(public_key);
701 assert!(public_key_data.is_ok());
702 let public_key_data = public_key_data.unwrap();
703 assert_eq!(*public_key_data.key_type(), KeyType::K256Public);
704
705 // Test that K256 keys successfully convert to JWK format
706 let private_jwk: Result<elliptic_curve::JwkEcKey, _> = (&private_key_data).try_into();
707 assert!(private_jwk.is_ok());
708 let private_jwk = private_jwk.unwrap();
709 assert_eq!(private_jwk.crv(), "secp256k1");
710
711 let public_jwk: Result<elliptic_curve::JwkEcKey, _> = (&public_key_data).try_into();
712 assert!(public_jwk.is_ok());
713 let public_jwk = public_jwk.unwrap();
714 assert_eq!(public_jwk.crv(), "secp256k1");
715
716 Ok(())
717 }
718
719 #[test]
720 fn test_try_into_jwk_keydata() -> Result<()> {
721 let private_key = "did:key:z42tnbHmmnhF11nwSnp5kQJbcZQw2Vbw5WF3ABDSxPtDgU2o";
722 let public_key = "did:key:zDnaeXduWbJ1b1Kgjf3uCdCpMDF1LEDizUiyxAxGwerou3Nh2";
723
724 let private_key_data = identify_key(private_key);
725 assert!(private_key_data.is_ok());
726 let private_key_data = private_key_data.unwrap();
727 assert_eq!(*private_key_data.key_type(), KeyType::P256Private);
728
729 let public_key_data = identify_key(public_key);
730 assert!(public_key_data.is_ok());
731 let public_key_data = public_key_data.unwrap();
732 assert_eq!(*public_key_data.key_type(), KeyType::P256Public);
733
734 // Test TryInto with KeyData directly
735 let private_jwk: Result<JwkEcKey, KeyError> = (&private_key_data).try_into();
736 assert!(private_jwk.is_ok());
737
738 let public_jwk: Result<JwkEcKey, KeyError> = (&public_key_data).try_into();
739 assert!(public_jwk.is_ok());
740
741 Ok(())
742 }
743
744 #[test]
745 fn test_generate_key_p256_private() -> Result<()> {
746 let key_data = generate_key(KeyType::P256Private)?;
747 assert_eq!(*key_data.key_type(), KeyType::P256Private);
748 assert_eq!(key_data.bytes().len(), 32); // P-256 private keys are 32 bytes
749
750 // Test that we can sign with the generated key
751 let content = "test content".as_bytes();
752 let signature = sign(&key_data, content)?;
753 let validation = validate(&key_data, &signature, content);
754 assert!(validation.is_ok());
755
756 Ok(())
757 }
758
759 #[test]
760 fn test_generate_key_k256_private() -> Result<()> {
761 let key_data = generate_key(KeyType::K256Private)?;
762 assert_eq!(*key_data.key_type(), KeyType::K256Private);
763 assert_eq!(key_data.bytes().len(), 32); // K-256 private keys are 32 bytes
764
765 // Test that we can sign with the generated key
766 let content = "test content".as_bytes();
767 let signature = sign(&key_data, content)?;
768 let validation = validate(&key_data, &signature, content);
769 assert!(validation.is_ok());
770
771 Ok(())
772 }
773
774 #[test]
775 fn test_generate_key_public_not_supported() {
776 let result = generate_key(KeyType::P256Public);
777 assert!(matches!(
778 result,
779 Err(KeyError::PublicKeyGenerationNotSupported)
780 ));
781
782 let result = generate_key(KeyType::K256Public);
783 assert!(matches!(
784 result,
785 Err(KeyError::PublicKeyGenerationNotSupported)
786 ));
787 }
788
789 #[test]
790 fn test_generate_key_uniqueness() -> Result<()> {
791 // Generate multiple keys and ensure they're different
792 let key1 = generate_key(KeyType::P256Private)?;
793 let key2 = generate_key(KeyType::P256Private)?;
794 assert_ne!(key1.bytes(), key2.bytes());
795
796 let key3 = generate_key(KeyType::K256Private)?;
797 let key4 = generate_key(KeyType::K256Private)?;
798 assert_ne!(key3.bytes(), key4.bytes());
799
800 Ok(())
801 }
802
803 #[test]
804 fn test_keydata_display_p256_private() -> Result<()> {
805 // Generate a P-256 private key
806 let original_key = generate_key(KeyType::P256Private)?;
807
808 // Convert to string using Display trait
809 let key_string = format!("{}", original_key);
810
811 // Verify it has the correct prefix
812 assert!(key_string.starts_with("did:key:"));
813
814 // Parse it back using identify_key
815 let parsed_key = identify_key(&key_string)?;
816
817 // Verify round-trip: key type should match
818 assert_eq!(original_key.key_type(), parsed_key.key_type());
819
820 // Verify round-trip: bytes should match
821 assert_eq!(original_key.bytes(), parsed_key.bytes());
822
823 // Test signing and verification with both keys
824 let content = "test message for p256".as_bytes();
825
826 // Sign with original key
827 let signature = sign(&original_key, content)?;
828
829 // Verify with original key
830 validate(&original_key, &signature, content)?;
831
832 // Verify with parsed key
833 validate(&parsed_key, &signature, content)?;
834
835 // Sign with parsed key
836 let signature2 = sign(&parsed_key, content)?;
837
838 // Verify both signatures are the same (deterministic signing)
839 // Note: ECDSA signatures may not be deterministic, so we just verify both work
840 validate(&original_key, &signature2, content)?;
841 validate(&parsed_key, &signature2, content)?;
842
843 Ok(())
844 }
845
846 #[test]
847 fn test_keydata_display_k256_private() -> Result<()> {
848 // Generate a K-256 private key
849 let original_key = generate_key(KeyType::K256Private)?;
850
851 // Convert to string using Display trait
852 let key_string = format!("{}", original_key);
853
854 // Verify it has the correct prefix
855 assert!(key_string.starts_with("did:key:"));
856
857 // Parse it back using identify_key
858 let parsed_key = identify_key(&key_string)?;
859
860 // Verify round-trip: key type should match
861 assert_eq!(original_key.key_type(), parsed_key.key_type());
862
863 // Verify round-trip: bytes should match
864 assert_eq!(original_key.bytes(), parsed_key.bytes());
865
866 // Test signing and verification with both keys
867 let content = "test message for k256".as_bytes();
868
869 // Sign with original key
870 let signature = sign(&original_key, content)?;
871
872 // Verify with original key
873 validate(&original_key, &signature, content)?;
874
875 // Verify with parsed key
876 validate(&parsed_key, &signature, content)?;
877
878 // Sign with parsed key
879 let signature2 = sign(&parsed_key, content)?;
880
881 // Verify both signatures work
882 validate(&original_key, &signature2, content)?;
883 validate(&parsed_key, &signature2, content)?;
884
885 Ok(())
886 }
887
888 #[test]
889 fn test_keydata_display_existing_keys() -> Result<()> {
890 // Test with known existing keys from other tests
891 let p256_private_key = "did:key:z42tnbHmmnhF11nwSnp5kQJbcZQw2Vbw5WF3ABDSxPtDgU2o";
892 let k256_private_key = "did:key:z3vLY4nbXy2rV4Qr65gUtfnSF3A8Be7gmYzUiCX6eo2PR1Rt";
893
894 // Parse and re-serialize P-256 key
895 let parsed_p256 = identify_key(p256_private_key)?;
896 let reserialized_p256 = format!("{}", parsed_p256);
897 assert_eq!(p256_private_key, reserialized_p256);
898
899 // Parse and re-serialize K-256 key
900 let parsed_k256 = identify_key(k256_private_key)?;
901 let reserialized_k256 = format!("{}", parsed_k256);
902 assert_eq!(k256_private_key, reserialized_k256);
903
904 Ok(())
905 }
906
907 #[test]
908 fn test_keydata_display_cross_verification() -> Result<()> {
909 // Generate keys and test cross-verification scenarios
910 let p256_key = generate_key(KeyType::P256Private)?;
911 let k256_key = generate_key(KeyType::K256Private)?;
912
913 // Serialize both keys
914 let p256_string = format!("{}", p256_key);
915 let k256_string = format!("{}", k256_key);
916
917 // Verify they produce different strings
918 assert_ne!(p256_string, k256_string);
919
920 // Parse them back
921 let parsed_p256 = identify_key(&p256_string)?;
922 let parsed_k256 = identify_key(&k256_string)?;
923
924 // Verify types are preserved
925 assert_eq!(*parsed_p256.key_type(), KeyType::P256Private);
926 assert_eq!(*parsed_k256.key_type(), KeyType::K256Private);
927
928 // Test that keys from different curves can't be used interchangeably
929 let content = "cross verification test".as_bytes();
930
931 // Sign with P-256
932 let p256_signature = sign(&p256_key, content)?;
933
934 // Sign with K-256
935 let k256_signature = sign(&k256_key, content)?;
936
937 // Verify P-256 signature with P-256 key (should work)
938 assert!(validate(&p256_key, &p256_signature, content).is_ok());
939 assert!(validate(&parsed_p256, &p256_signature, content).is_ok());
940
941 // Verify K-256 signature with K-256 key (should work)
942 assert!(validate(&k256_key, &k256_signature, content).is_ok());
943 assert!(validate(&parsed_k256, &k256_signature, content).is_ok());
944
945 // Cross-verification should fail
946 assert!(validate(&p256_key, &k256_signature, content).is_err());
947 assert!(validate(&k256_key, &p256_signature, content).is_err());
948
949 Ok(())
950 }
951
952 #[test]
953 fn test_keydata_display_format_consistency() -> Result<()> {
954 // Test that the Display format matches expected patterns
955 let p256_key = generate_key(KeyType::P256Private)?;
956 let k256_key = generate_key(KeyType::K256Private)?;
957
958 let p256_string = format!("{}", p256_key);
959 let k256_string = format!("{}", k256_key);
960
961 // Verify format structure
962 assert!(p256_string.starts_with("did:key:z"));
963 assert!(k256_string.starts_with("did:key:z"));
964
965 // Verify they can be parsed
966 let _parsed_p256 = identify_key(&p256_string)?;
967 let _parsed_k256 = identify_key(&k256_string)?;
968
969 // Verify string lengths are reasonable (multibase encoded keys should be consistent length)
970 // P-256 private keys: 2 bytes prefix + 32 bytes key = 34 bytes -> ~46 chars base58 + "did:key:z" prefix
971 assert!(p256_string.len() > 50 && p256_string.len() < 60);
972
973 // K-256 private keys: 2 bytes prefix + 32 bytes key = 34 bytes -> ~46 chars base58 + "did:key:z" prefix
974 assert!(k256_string.len() > 50 && k256_string.len() < 60);
975
976 Ok(())
977 }
978
979 #[test]
980 fn test_complete_workflow_demonstration() -> Result<()> {
981 println!("\n=== KeyData Display Implementation Test ===");
982
983 // Step 1: Generate keys
984 println!("1. Generating keys...");
985 let p256_key = generate_key(KeyType::P256Private)?;
986 let k256_key = generate_key(KeyType::K256Private)?;
987
988 // Step 2: Display keys (serialize)
989 println!("2. Serializing keys to DID format...");
990 let p256_did = format!("{}", p256_key);
991 let k256_did = format!("{}", k256_key);
992 println!(" P-256 DID: {}", p256_did);
993 println!(" K-256 DID: {}", k256_did);
994
995 // Step 3: Parse keys back (identify)
996 println!("3. Parsing DIDs back to KeyData...");
997 let parsed_p256 = identify_key(&p256_did)?;
998 let parsed_k256 = identify_key(&k256_did)?;
999 println!(" P-256 parsed successfully: {:?}", parsed_p256.key_type());
1000 println!(" K-256 parsed successfully: {:?}", parsed_k256.key_type());
1001
1002 // Step 4: Verify round-trip
1003 println!("4. Verifying round-trip integrity...");
1004 assert_eq!(p256_key.bytes(), parsed_p256.bytes());
1005 assert_eq!(k256_key.bytes(), parsed_k256.bytes());
1006 println!(" Round-trip successful for both keys!");
1007
1008 // Step 5: Sign and verify
1009 println!("5. Testing signing and verification...");
1010 let test_data = "Hello AT Protocol!".as_bytes();
1011
1012 // Sign with original keys
1013 let p256_signature = sign(&p256_key, test_data)?;
1014 let k256_signature = sign(&k256_key, test_data)?;
1015
1016 // Verify with parsed keys
1017 validate(&parsed_p256, &p256_signature, test_data)?;
1018 validate(&parsed_k256, &k256_signature, test_data)?;
1019 println!(" Signatures verified successfully with parsed keys!");
1020
1021 // Step 6: Cross-verification should fail
1022 println!("6. Testing cross-curve verification (should fail)...");
1023 assert!(validate(&parsed_p256, &k256_signature, test_data).is_err());
1024 assert!(validate(&parsed_k256, &p256_signature, test_data).is_err());
1025 println!(" Cross-curve verification correctly failed!");
1026
1027 println!("=== All tests completed successfully! ===\n");
1028
1029 Ok(())
1030 }
1031
1032 #[test]
1033 fn test_to_public_p256() -> Result<()> {
1034 // Generate a P-256 private key
1035 let private_key = generate_key(KeyType::P256Private)?;
1036
1037 // Convert to public key
1038 let public_key = to_public(&private_key)?;
1039
1040 // Verify the key type is correct
1041 assert_eq!(*public_key.key_type(), KeyType::P256Public);
1042
1043 // Test that the derived public key can verify signatures from the private key
1044 let content = "test message for p256 public key derivation".as_bytes();
1045 let signature = sign(&private_key, content)?;
1046
1047 // Public key should be able to verify the signature
1048 validate(&public_key, &signature, content)?;
1049
1050 // Test that the public key produces a valid DID string
1051 let public_key_did = format!("{}", public_key);
1052 assert!(public_key_did.starts_with("did:key:"));
1053
1054 // Parse the DID back and verify it's the same
1055 let parsed_public_key = identify_key(&public_key_did)?;
1056 assert_eq!(*parsed_public_key.key_type(), KeyType::P256Public);
1057 assert_eq!(public_key.bytes(), parsed_public_key.bytes());
1058
1059 Ok(())
1060 }
1061
1062 #[test]
1063 fn test_to_public_k256() -> Result<()> {
1064 // Generate a K-256 private key
1065 let private_key = generate_key(KeyType::K256Private)?;
1066
1067 // Convert to public key
1068 let public_key = to_public(&private_key)?;
1069
1070 // Verify the key type is correct
1071 assert_eq!(*public_key.key_type(), KeyType::K256Public);
1072
1073 // Test that the derived public key can verify signatures from the private key
1074 let content = "test message for k256 public key derivation".as_bytes();
1075 let signature = sign(&private_key, content)?;
1076
1077 // Public key should be able to verify the signature
1078 validate(&public_key, &signature, content)?;
1079
1080 // Test that the public key produces a valid DID string
1081 let public_key_did = format!("{}", public_key);
1082 assert!(public_key_did.starts_with("did:key:"));
1083
1084 // Parse the DID back and verify it's the same
1085 let parsed_public_key = identify_key(&public_key_did)?;
1086 assert_eq!(*parsed_public_key.key_type(), KeyType::K256Public);
1087 assert_eq!(public_key.bytes(), parsed_public_key.bytes());
1088
1089 Ok(())
1090 }
1091
1092 #[test]
1093 fn test_to_public_with_public_keys() -> Result<()> {
1094 // Test that passing a public key returns the same key
1095 let p256_private = generate_key(KeyType::P256Private)?;
1096 let p256_public = to_public(&p256_private)?;
1097
1098 // Calling to_public on a public key should return the same key
1099 let result = to_public(&p256_public)?;
1100 assert_eq!(*result.key_type(), KeyType::P256Public);
1101 assert_eq!(p256_public.bytes(), result.bytes());
1102
1103 let k256_private = generate_key(KeyType::K256Private)?;
1104 let k256_public = to_public(&k256_private)?;
1105
1106 let result = to_public(&k256_public)?;
1107 assert_eq!(*result.key_type(), KeyType::K256Public);
1108 assert_eq!(k256_public.bytes(), result.bytes());
1109
1110 Ok(())
1111 }
1112
1113 #[test]
1114 fn test_to_public_existing_keys() -> Result<()> {
1115 // Test with known private keys to ensure consistent behavior
1116 let p256_private_key = "did:key:z42tj8ZrAza9WkewDELwWMN37TS3coEbGdZh8bp1URfMVnpx";
1117 let k256_private_key = "did:key:z3vLW46Z1UHwnr7vN33MoFt2sBQDQagn9HTvWnsQDHegUixP";
1118
1119 // Parse the private keys
1120 let parsed_p256_private = identify_key(p256_private_key)?;
1121 let parsed_k256_private = identify_key(k256_private_key)?;
1122
1123 // Convert to public keys
1124 let p256_public = to_public(&parsed_p256_private)?;
1125 let k256_public = to_public(&parsed_k256_private)?;
1126
1127 // Verify types
1128 assert_eq!(*p256_public.key_type(), KeyType::P256Public);
1129 assert_eq!(*k256_public.key_type(), KeyType::K256Public);
1130
1131 // Test signing and verification
1132 let content = "test with existing keys".as_bytes();
1133
1134 let p256_signature = sign(&parsed_p256_private, content)?;
1135 let k256_signature = sign(&parsed_k256_private, content)?;
1136
1137 // Verify with derived public keys
1138 validate(&p256_public, &p256_signature, content)?;
1139 validate(&k256_public, &k256_signature, content)?;
1140
1141 Ok(())
1142 }
1143
1144 #[test]
1145 fn test_to_public_comprehensive_workflow() -> Result<()> {
1146 println!("\n=== Public Key Derivation Test ===");
1147
1148 // Generate private keys
1149 println!("1. Generating private keys...");
1150 let p256_private = generate_key(KeyType::P256Private)?;
1151 let k256_private = generate_key(KeyType::K256Private)?;
1152
1153 // Derive public keys
1154 println!("2. Deriving public keys...");
1155 let p256_public = to_public(&p256_private)?;
1156 let k256_public = to_public(&k256_private)?;
1157
1158 // Serialize all keys
1159 println!("3. Serializing keys to DID format...");
1160 let p256_private_did = format!("{}", p256_private);
1161 let p256_public_did = format!("{}", p256_public);
1162 let k256_private_did = format!("{}", k256_private);
1163 let k256_public_did = format!("{}", k256_public);
1164
1165 println!(" P-256 Private: {}", p256_private_did);
1166 println!(" P-256 Public: {}", p256_public_did);
1167 println!(" K-256 Private: {}", k256_private_did);
1168 println!(" K-256 Public: {}", k256_public_did);
1169
1170 // Verify different DID patterns
1171 assert_ne!(p256_private_did, p256_public_did);
1172 assert_ne!(k256_private_did, k256_public_did);
1173 assert_ne!(p256_public_did, k256_public_did);
1174
1175 // Test signing and verification
1176 println!("4. Testing signature verification...");
1177 let test_data = "Public key derivation test data".as_bytes();
1178
1179 let p256_signature = sign(&p256_private, test_data)?;
1180 let k256_signature = sign(&k256_private, test_data)?;
1181
1182 // Verify with derived public keys
1183 validate(&p256_public, &p256_signature, test_data)?;
1184 validate(&k256_public, &k256_signature, test_data)?;
1185 println!(" Signatures verified successfully with derived public keys!");
1186
1187 // Parse public key DIDs and re-verify
1188 println!("5. Testing DID round-trip with public keys...");
1189 let parsed_p256_public = identify_key(&p256_public_did)?;
1190 let parsed_k256_public = identify_key(&k256_public_did)?;
1191
1192 validate(&parsed_p256_public, &p256_signature, test_data)?;
1193 validate(&parsed_k256_public, &k256_signature, test_data)?;
1194 println!(" Parsed public keys also verify signatures correctly!");
1195
1196 println!("=== Public key derivation workflow completed successfully! ===\n");
1197
1198 Ok(())
1199 }
1200
1201 #[test]
1202 fn test_to_public_key_properties() -> Result<()> {
1203 // Test that derived public keys have expected properties
1204 let p256_private = generate_key(KeyType::P256Private)?;
1205 let k256_private = generate_key(KeyType::K256Private)?;
1206
1207 let p256_public = to_public(&p256_private)?;
1208 let k256_public = to_public(&k256_private)?;
1209
1210 // P-256 public keys should be 65 bytes (uncompressed) or 33 bytes (compressed)
1211 // SEC1 format is typically uncompressed for public keys: 0x04 + 32 bytes x + 32 bytes y
1212 assert!(p256_public.bytes().len() == 65 || p256_public.bytes().len() == 33);
1213
1214 // K-256 public keys should also be 65 bytes (uncompressed) or 33 bytes (compressed)
1215 assert!(k256_public.bytes().len() == 65 || k256_public.bytes().len() == 33);
1216
1217 // Test that multiple derivations from the same private key produce the same public key
1218 let p256_public2 = to_public(&p256_private)?;
1219 let k256_public2 = to_public(&k256_private)?;
1220
1221 assert_eq!(p256_public.bytes(), p256_public2.bytes());
1222 assert_eq!(k256_public.bytes(), k256_public2.bytes());
1223
1224 Ok(())
1225 }
1226
1227 #[test]
1228 fn test_to_public_with_existing_public_keys() -> Result<()> {
1229 // Test with known public keys from the test suite
1230 let p256_public_key = "did:key:zDnaeXduWbJ1b1Kgjf3uCdCpMDF1LEDizUiyxAxGwerou3Nh2";
1231 let k256_public_key = "did:key:zQ3shNzMp4oaaQ1gQRzCxMGXFrSW3NEM1M9T6KCY9eA7HhyEA";
1232
1233 // Parse the public keys
1234 let parsed_p256_public = identify_key(p256_public_key)?;
1235 let parsed_k256_public = identify_key(k256_public_key)?;
1236
1237 // Verify they are public keys
1238 assert_eq!(*parsed_p256_public.key_type(), KeyType::P256Public);
1239 assert_eq!(*parsed_k256_public.key_type(), KeyType::K256Public);
1240
1241 // Calling to_public should return the same keys
1242 let same_p256_public = to_public(&parsed_p256_public)?;
1243 let same_k256_public = to_public(&parsed_k256_public)?;
1244
1245 // Verify they are identical
1246 assert_eq!(*same_p256_public.key_type(), KeyType::P256Public);
1247 assert_eq!(*same_k256_public.key_type(), KeyType::K256Public);
1248 assert_eq!(parsed_p256_public.bytes(), same_p256_public.bytes());
1249 assert_eq!(parsed_k256_public.bytes(), same_k256_public.bytes());
1250
1251 // Verify they serialize to the same DID strings
1252 assert_eq!(format!("{}", same_p256_public), p256_public_key);
1253 assert_eq!(format!("{}", same_k256_public), k256_public_key);
1254
1255 Ok(())
1256 }
1257
1258 // ===== P-384 SPECIFIC TESTS =====
1259
1260 #[test]
1261 fn test_generate_key_p384_private() -> Result<()> {
1262 let key_data = generate_key(KeyType::P384Private)?;
1263 assert_eq!(*key_data.key_type(), KeyType::P384Private);
1264 assert_eq!(key_data.bytes().len(), 48); // P-384 private keys are 48 bytes
1265
1266 // Test that we can sign with the generated key
1267 let content = "test content for p384".as_bytes();
1268 let signature = sign(&key_data, content)?;
1269 let validation = validate(&key_data, &signature, content);
1270 assert!(validation.is_ok());
1271
1272 Ok(())
1273 }
1274
1275 #[test]
1276 fn test_generate_key_p384_public_not_supported() {
1277 let result = generate_key(KeyType::P384Public);
1278 assert!(matches!(
1279 result,
1280 Err(KeyError::PublicKeyGenerationNotSupported)
1281 ));
1282 }
1283
1284 #[test]
1285 fn test_generate_key_p384_uniqueness() -> Result<()> {
1286 // Generate multiple P-384 keys and ensure they're different
1287 let key1 = generate_key(KeyType::P384Private)?;
1288 let key2 = generate_key(KeyType::P384Private)?;
1289 assert_ne!(key1.bytes(), key2.bytes());
1290
1291 Ok(())
1292 }
1293
1294 #[test]
1295 fn test_sign_and_validate_p384() -> Result<()> {
1296 // Generate a P-384 private key
1297 let private_key = generate_key(KeyType::P384Private)?;
1298
1299 // Derive the corresponding public key
1300 let public_key = to_public(&private_key)?;
1301 assert_eq!(*public_key.key_type(), KeyType::P384Public);
1302
1303 let content = "hello world p384 test".as_bytes();
1304
1305 // Sign with private key
1306 let signature = sign(&private_key, content)?;
1307 assert!(!signature.is_empty());
1308
1309 // Verify with public key
1310 validate(&public_key, &signature, content)?;
1311
1312 // Verify with private key (should also work)
1313 validate(&private_key, &signature, content)?;
1314
1315 // Test signature verification fails with wrong content
1316 let wrong_content = "wrong content".as_bytes();
1317 assert!(validate(&public_key, &signature, wrong_content).is_err());
1318
1319 Ok(())
1320 }
1321
1322 #[test]
1323 fn test_p384_keydata_display_round_trip() -> Result<()> {
1324 // Generate a P-384 private key
1325 let original_key = generate_key(KeyType::P384Private)?;
1326
1327 // Convert to string using Display trait
1328 let key_string = format!("{}", original_key);
1329
1330 // Verify it has the correct prefix
1331 assert!(key_string.starts_with("did:key:"));
1332
1333 // Parse it back using identify_key
1334 let parsed_key = identify_key(&key_string)?;
1335
1336 // Verify round-trip: key type should match
1337 assert_eq!(original_key.key_type(), parsed_key.key_type());
1338
1339 // Verify round-trip: bytes should match
1340 assert_eq!(original_key.bytes(), parsed_key.bytes());
1341
1342 // Test signing and verification with both keys
1343 let content = "test message for p384 round trip".as_bytes();
1344
1345 // Sign with original key
1346 let signature = sign(&original_key, content)?;
1347
1348 // Verify with original key
1349 validate(&original_key, &signature, content)?;
1350
1351 // Verify with parsed key
1352 validate(&parsed_key, &signature, content)?;
1353
1354 // Sign with parsed key
1355 let signature2 = sign(&parsed_key, content)?;
1356
1357 // Verify both signatures work
1358 validate(&original_key, &signature2, content)?;
1359 validate(&parsed_key, &signature2, content)?;
1360
1361 Ok(())
1362 }
1363
1364 #[test]
1365 fn test_p384_to_public_key_derivation() -> Result<()> {
1366 // Generate a P-384 private key
1367 let private_key = generate_key(KeyType::P384Private)?;
1368
1369 // Convert to public key
1370 let public_key = to_public(&private_key)?;
1371
1372 // Verify the key type is correct
1373 assert_eq!(*public_key.key_type(), KeyType::P384Public);
1374
1375 // Test that the derived public key can verify signatures from the private key
1376 let content = "test message for p384 public key derivation".as_bytes();
1377 let signature = sign(&private_key, content)?;
1378
1379 // Public key should be able to verify the signature
1380 validate(&public_key, &signature, content)?;
1381
1382 // Test that the public key produces a valid DID string
1383 let public_key_did = format!("{}", public_key);
1384 assert!(public_key_did.starts_with("did:key:"));
1385
1386 // Parse the DID back and verify it's the same
1387 let parsed_public_key = identify_key(&public_key_did)?;
1388 assert_eq!(*parsed_public_key.key_type(), KeyType::P384Public);
1389 assert_eq!(public_key.bytes(), parsed_public_key.bytes());
1390
1391 // Calling to_public on a public key should return the same key
1392 let result = to_public(&public_key)?;
1393 assert_eq!(*result.key_type(), KeyType::P384Public);
1394 assert_eq!(public_key.bytes(), result.bytes());
1395
1396 Ok(())
1397 }
1398
1399 #[test]
1400 fn test_p384_jwk_conversion() -> Result<()> {
1401 // Generate P-384 keys
1402 let private_key = generate_key(KeyType::P384Private)?;
1403 let public_key = to_public(&private_key)?;
1404
1405 // Test private key to JWK conversion
1406 let private_jwk: Result<elliptic_curve::JwkEcKey, _> = (&private_key).try_into();
1407 assert!(private_jwk.is_ok());
1408
1409 // Test public key to JWK conversion
1410 let public_jwk: Result<elliptic_curve::JwkEcKey, _> = (&public_key).try_into();
1411 assert!(public_jwk.is_ok());
1412
1413 Ok(())
1414 }
1415
1416 #[test]
1417 fn test_p384_key_properties() -> Result<()> {
1418 // Test that P-384 keys have expected properties
1419 let private_key = generate_key(KeyType::P384Private)?;
1420 let public_key = to_public(&private_key)?;
1421
1422 // P-384 private keys should be 48 bytes
1423 assert_eq!(private_key.bytes().len(), 48);
1424
1425 // P-384 public keys should be 97 bytes (uncompressed) or 49 bytes (compressed)
1426 // SEC1 format: 0x04 + 48 bytes x + 48 bytes y = 97 bytes uncompressed
1427 // or 0x02/0x03 + 48 bytes x = 49 bytes compressed
1428 assert!(public_key.bytes().len() == 97 || public_key.bytes().len() == 49);
1429
1430 // Test that multiple derivations from the same private key produce the same public key
1431 let public_key2 = to_public(&private_key)?;
1432 assert_eq!(public_key.bytes(), public_key2.bytes());
1433
1434 Ok(())
1435 }
1436
1437 #[test]
1438 fn test_p384_cross_curve_verification_fails() -> Result<()> {
1439 // Generate keys from different curves
1440 let p256_key = generate_key(KeyType::P256Private)?;
1441 let p384_key = generate_key(KeyType::P384Private)?;
1442 let k256_key = generate_key(KeyType::K256Private)?;
1443
1444 // Get their public keys
1445 let p256_public = to_public(&p256_key)?;
1446 let p384_public = to_public(&p384_key)?;
1447 let k256_public = to_public(&k256_key)?;
1448
1449 let content = "cross curve verification test".as_bytes();
1450
1451 // Sign with each private key
1452 let p256_signature = sign(&p256_key, content)?;
1453 let p384_signature = sign(&p384_key, content)?;
1454 let k256_signature = sign(&k256_key, content)?;
1455
1456 // Verify each signature works with its corresponding key
1457 validate(&p256_public, &p256_signature, content)?;
1458 validate(&p384_public, &p384_signature, content)?;
1459 validate(&k256_public, &k256_signature, content)?;
1460
1461 // Cross-verification should fail - P-384 vs others
1462 assert!(validate(&p256_public, &p384_signature, content).is_err());
1463 assert!(validate(&p384_public, &p256_signature, content).is_err());
1464 assert!(validate(&k256_public, &p384_signature, content).is_err());
1465 assert!(validate(&p384_public, &k256_signature, content).is_err());
1466
1467 Ok(())
1468 }
1469
1470 #[test]
1471 fn test_p384_sign_with_public_key_fails() {
1472 let private_key = generate_key(KeyType::P384Private).unwrap();
1473 let public_key = to_public(&private_key).unwrap();
1474
1475 let content = "test content".as_bytes();
1476
1477 // Signing with public key should fail
1478 let result = sign(&public_key, content);
1479 assert!(matches!(
1480 result,
1481 Err(KeyError::PrivateKeyRequiredForSignature)
1482 ));
1483 }
1484
1485 #[test]
1486 fn test_p384_comprehensive_workflow() -> Result<()> {
1487 println!("\n=== P-384 Comprehensive Workflow Test ===");
1488
1489 // Step 1: Generate P-384 private key
1490 println!("1. Generating P-384 private key...");
1491 let private_key = generate_key(KeyType::P384Private)?;
1492 assert_eq!(*private_key.key_type(), KeyType::P384Private);
1493 assert_eq!(private_key.bytes().len(), 48);
1494
1495 // Step 2: Derive public key
1496 println!("2. Deriving P-384 public key...");
1497 let public_key = to_public(&private_key)?;
1498 assert_eq!(*public_key.key_type(), KeyType::P384Public);
1499
1500 // Step 3: Serialize keys to DID format
1501 println!("3. Serializing keys to DID format...");
1502 let private_did = format!("{}", private_key);
1503 let public_did = format!("{}", public_key);
1504 println!(" P-384 Private: {}", private_did);
1505 println!(" P-384 Public: {}", public_did);
1506
1507 assert!(private_did.starts_with("did:key:"));
1508 assert!(public_did.starts_with("did:key:"));
1509 assert_ne!(private_did, public_did);
1510
1511 // Step 4: Parse DIDs back to KeyData
1512 println!("4. Parsing DIDs back to KeyData...");
1513 let parsed_private = identify_key(&private_did)?;
1514 let parsed_public = identify_key(&public_did)?;
1515
1516 assert_eq!(*parsed_private.key_type(), KeyType::P384Private);
1517 assert_eq!(*parsed_public.key_type(), KeyType::P384Public);
1518
1519 // Step 5: Verify round-trip integrity
1520 println!("5. Verifying round-trip integrity...");
1521 assert_eq!(private_key.bytes(), parsed_private.bytes());
1522 assert_eq!(public_key.bytes(), parsed_public.bytes());
1523
1524 // Step 6: Test signing and verification
1525 println!("6. Testing signing and verification...");
1526 let test_data = "P-384 comprehensive test data".as_bytes();
1527
1528 // Sign with original private key
1529 let signature = sign(&private_key, test_data)?;
1530
1531 // Verify with all key variants
1532 validate(&private_key, &signature, test_data)?;
1533 validate(&public_key, &signature, test_data)?;
1534 validate(&parsed_private, &signature, test_data)?;
1535 validate(&parsed_public, &signature, test_data)?;
1536
1537 // Step 7: Test JWK conversion
1538 println!("7. Testing JWK conversion...");
1539 let private_jwk: elliptic_curve::JwkEcKey = (&private_key).try_into()?;
1540 let public_jwk: elliptic_curve::JwkEcKey = (&public_key).try_into()?;
1541
1542 assert_eq!(private_jwk.crv(), "P-384");
1543 assert_eq!(public_jwk.crv(), "P-384");
1544
1545 println!("=== P-384 comprehensive workflow completed successfully! ===\n");
1546
1547 Ok(())
1548 }
1549
1550 #[test]
1551 fn test_p384_multicodec_prefix_identification() -> Result<()> {
1552 // Test that we can identify P-384 keys by their multicodec prefixes
1553 let private_key = generate_key(KeyType::P384Private)?;
1554 let public_key = to_public(&private_key)?;
1555
1556 // Convert to DID strings
1557 let private_did = format!("{}", private_key);
1558 let public_did = format!("{}", public_key);
1559
1560 // Parse back and verify the multicodec prefixes were correctly identified
1561 let parsed_private = identify_key(&private_did)?;
1562 let parsed_public = identify_key(&public_did)?;
1563
1564 assert_eq!(*parsed_private.key_type(), KeyType::P384Private);
1565 assert_eq!(*parsed_public.key_type(), KeyType::P384Public);
1566
1567 // Verify the actual multicodec prefixes in the DID strings
1568 let private_value = did_method_key_value(&private_did);
1569 let public_value = did_method_key_value(&public_did);
1570
1571 let (_, private_decoded) = multibase::decode(private_value)?;
1572 let (_, public_decoded) = multibase::decode(public_value)?;
1573
1574 // Check the multicodec prefixes
1575 assert_eq!(&private_decoded[..2], &[0x13, 0x01]); // P-384 private key prefix
1576 assert_eq!(&public_decoded[..2], &[0x12, 0x00]); // P-384 public key prefix
1577
1578 Ok(())
1579 }
1580}