1use core::fmt::Debug;
11
12#[cfg(not(feature = "std"))]
13extern crate alloc;
14
15#[cfg(all(not(feature = "std"), any(feature = "signature", feature = "aead")))]
16use alloc::{boxed::Box, sync::Arc, vec::Vec};
17
18#[cfg(any(feature = "signature", feature = "aead"))]
19use core::marker::PhantomData;
20
21#[cfg(any(feature = "signature", feature = "aead"))]
22use core::future::Future;
23#[cfg(any(feature = "signature", feature = "aead"))]
24use core::pin::Pin;
25#[cfg(all(feature = "std", any(feature = "signature", feature = "aead")))]
26use std::sync::Arc;
27
28#[cfg(feature = "signature")]
29mod signing {
30 pub use crate::crypto::sign::ecdsa::{
31 DigestPrimitive, Secp256k1, Secp256k1Signature, Secp256k1SigningKey, SignPrimitive, Signature, SignatureSize,
32 SigningKey, VerifyPrimitive,
33 };
34 pub use crate::crypto::sign::elliptic_curve::generic_array::{ArrayLength, GenericArray};
35 pub use crate::crypto::sign::elliptic_curve::ops::{Invert, Reduce};
36 pub use crate::crypto::sign::elliptic_curve::point::PointCompression;
37 pub use crate::crypto::sign::elliptic_curve::scalar::Scalar;
38 pub use crate::crypto::sign::elliptic_curve::sec1::ModulusSize;
39 pub use crate::crypto::sign::elliptic_curve::sec1::{FromEncodedPoint, ToEncodedPoint};
40 pub use crate::crypto::sign::elliptic_curve::subtle::CtOption;
41 pub use crate::crypto::sign::elliptic_curve::{
42 AffinePoint, CurveArithmetic, Error as EllipticCurveError, FieldBytesSize, PrimeCurve,
43 };
44 pub use crate::crypto::sign::{
45 Error as SignatureError, Keypair, PrehashSigner, SignatureAlgorithmIdentifier, SignatureEncoding,
46 };
47
48 #[cfg(feature = "ecdh")]
49 pub use crate::crypto::sign::elliptic_curve::ecdh::diffie_hellman;
50 #[cfg(feature = "ecdh")]
51 pub use crate::crypto::sign::elliptic_curve::PublicKey;
52}
53
54#[cfg(feature = "signature")]
55use signing::*;
56
57#[cfg(feature = "aead")]
58mod encryption {
59 pub use crate::crypto::aead::{
60 Aead, AeadCore, Aes128Gcm, Aes128GcmOid, Aes256Gcm, Aes256GcmOid, Error as AeadError, Nonce,
61 };
62 pub use crate::crypto::common::typenum::Unsigned;
63}
64
65#[cfg(feature = "aead")]
66use encryption::*;
67
68#[cfg(any(feature = "signature", feature = "aead"))]
69mod common {
70 pub use crate::der::oid::AssociatedOid;
71 pub use crate::spki::AlgorithmIdentifierOwned;
72
73 #[cfg(feature = "signature")]
74 pub use crate::spki::EncodePublicKey;
75}
76
77#[cfg(any(feature = "signature", feature = "aead"))]
78use common::*;
79
80#[cfg(feature = "signature")]
81use crate::crypto::secret::SecretSlice;
82
83#[derive(Debug)]
93pub enum KeyError {
94 SpkiError(crate::spki::Error),
96
97 #[cfg(feature = "signature")]
99 EllipticCurveError(EllipticCurveError),
100
101 #[cfg(feature = "signature")]
103 SignatureError(SignatureError),
104
105 #[cfg(feature = "aead")]
107 AeadError(AeadError),
108
109 #[cfg(feature = "aead")]
111 NonceLengthError(crate::error::ReceivedExpectedError<usize, usize>),
112
113 UnsupportedOperation,
115}
116
117crate::impl_error_display!(unconditional KeyError {
118 SpkiError(e) => "SPKI error: {e}",
119 #[cfg(feature = "signature")]
120 EllipticCurveError(e) => "Elliptic curve error: {e}",
121 #[cfg(feature = "signature")]
122 SignatureError(e) => "Signature error: {e}",
123 #[cfg(feature = "aead")]
124 AeadError(e) => "AEAD error: {e}",
125 #[cfg(feature = "aead")]
126 NonceLengthError(e) => "Nonce length mismatch: {e}",
127 UnsupportedOperation => "Operation not supported by this key provider",
128});
129
130crate::impl_from!(crate::spki::Error => KeyError::SpkiError);
131crate::impl_from!(#[cfg(feature = "signature")] EllipticCurveError => KeyError::EllipticCurveError);
132crate::impl_from!(#[cfg(feature = "signature")] SignatureError => KeyError::SignatureError);
133crate::impl_from!(#[cfg(feature = "aead")] AeadError => KeyError::AeadError);
134
135#[cfg(feature = "signature")]
140#[derive(Debug, Clone)]
141pub enum SigningKeySpec {
142 Bytes(&'static [u8]),
144
145 Provider(Arc<dyn SigningKeyProvider>),
147}
148
149#[cfg(feature = "signature")]
150impl SigningKeySpec {
151 pub fn to_provider<C>(&self) -> Result<Arc<dyn SigningKeyProvider>, KeyError>
161 where
162 C: PrimeCurve + CurveArithmetic + DigestPrimitive + PointCompression + AssociatedOid + Send + Sync + 'static,
163 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C> + Reduce<C::Uint>,
164 SignatureSize<C>: ArrayLength<u8>,
165 FieldBytesSize<C>: ModulusSize,
166 AffinePoint<C>: VerifyPrimitive<C> + FromEncodedPoint<C> + ToEncodedPoint<C>,
167 SigningKey<C>: PrehashSigner<Signature<C>> + Keypair + Send + Sync + Debug + 'static,
168 <SigningKey<C> as Keypair>::VerifyingKey: EncodePublicKey,
169 Signature<C>: SignatureEncoding + SignatureAlgorithmIdentifier + Send + Sync + 'static,
170 {
171 match self {
172 SigningKeySpec::Bytes(bytes) => {
173 let field_bytes = GenericArray::from_slice(bytes);
174 let signing_key = SigningKey::<C>::from_bytes(field_bytes)?;
175 Ok(Arc::new(EcdsaKeyProvider::from(signing_key)))
176 }
177 SigningKeySpec::Provider(provider) => Ok(Arc::clone(provider)),
178 }
179 }
180}
181
182#[cfg(feature = "signature")]
197pub trait SigningKeyProvider: Send + Sync + Debug {
198 fn algorithm(&self) -> AlgorithmIdentifierOwned;
200
201 fn to_public_key_bytes(&self) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>>;
207
208 fn sign_prehash(&self, prehash: &[u8]) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>>;
223
224 fn key_agreement(
242 &self,
243 _peer_public_key: &[u8],
244 ) -> Pin<Box<dyn Future<Output = Result<SecretSlice<u8>, KeyError>> + Send + '_>> {
245 Box::pin(async { Err(KeyError::UnsupportedOperation) })
246 }
247}
248
249#[cfg(feature = "signature")]
265pub struct InMemorySigningKeyProvider<K, S>
266where
267 K: PrehashSigner<S> + Keypair,
268 S: SignatureEncoding,
269{
270 signing_key: K,
271 _sig: PhantomData<S>,
272}
273
274#[cfg(feature = "signature")]
275impl<K, S> From<K> for InMemorySigningKeyProvider<K, S>
276where
277 K: PrehashSigner<S> + Keypair,
278 S: SignatureEncoding,
279{
280 fn from(signing_key: K) -> Self {
281 InMemorySigningKeyProvider { signing_key, _sig: PhantomData }
282 }
283}
284
285#[cfg(feature = "signature")]
286impl<K, S> Debug for InMemorySigningKeyProvider<K, S>
287where
288 K: PrehashSigner<S> + Keypair + Debug,
289 S: SignatureEncoding,
290{
291 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
292 f.debug_struct("InMemoryKeyProvider")
293 .field("signing_key", &self.signing_key)
294 .finish()
295 }
296}
297
298#[cfg(feature = "signature")]
299impl<K, S> SigningKeyProvider for InMemorySigningKeyProvider<K, S>
300where
301 K: PrehashSigner<S> + Keypair + Send + Sync + Debug + 'static,
302 K::VerifyingKey: EncodePublicKey,
303 S: SignatureEncoding + SignatureAlgorithmIdentifier + Send + Sync + 'static,
304{
305 fn algorithm(&self) -> AlgorithmIdentifierOwned {
306 AlgorithmIdentifierOwned { oid: S::ALGORITHM_OID, parameters: None }
307 }
308
309 fn to_public_key_bytes(&self) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
310 let result = self
311 .signing_key
312 .verifying_key()
313 .to_public_key_der()
314 .map(|der| der.into_vec())
315 .map_err(KeyError::from);
316
317 Box::pin(async move { result })
318 }
319
320 fn sign_prehash(&self, prehash: &[u8]) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
321 let result = self
322 .signing_key
323 .sign_prehash(prehash)
324 .map(|signature: S| signature.to_bytes().as_ref().to_vec())
325 .map_err(KeyError::from);
326
327 Box::pin(async move { result })
328 }
329}
330
331#[cfg(feature = "signature")]
333impl<K, S> SigningKeyProvider for Arc<InMemorySigningKeyProvider<K, S>>
334where
335 K: PrehashSigner<S> + Keypair + Send + Sync + Debug + 'static,
336 K::VerifyingKey: EncodePublicKey,
337 S: SignatureEncoding + SignatureAlgorithmIdentifier + Send + Sync + 'static,
338{
339 fn algorithm(&self) -> AlgorithmIdentifierOwned {
340 self.as_ref().algorithm()
341 }
342
343 fn to_public_key_bytes(&self) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
344 self.as_ref().to_public_key_bytes()
345 }
346
347 fn sign_prehash(&self, prehash: &[u8]) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
348 self.as_ref().sign_prehash(prehash)
349 }
350}
351
352#[cfg(all(feature = "signature", feature = "secp256k1"))]
354pub type Secp256k1Provider = InMemorySigningKeyProvider<Secp256k1SigningKey, Secp256k1Signature>;
355
356#[cfg(all(feature = "signature", feature = "secp256k1"))]
369pub struct EcdsaKeyProvider<C>
370where
371 C: PrimeCurve + CurveArithmetic,
372 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
373 SignatureSize<C>: ArrayLength<u8>,
374{
375 signing_key: SigningKey<C>,
376}
377
378#[cfg(all(feature = "signature", feature = "secp256k1"))]
379impl<C> From<SigningKey<C>> for EcdsaKeyProvider<C>
380where
381 C: PrimeCurve + CurveArithmetic,
382 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
383 SignatureSize<C>: ArrayLength<u8>,
384{
385 fn from(signing_key: SigningKey<C>) -> Self {
386 EcdsaKeyProvider { signing_key }
387 }
388}
389
390#[cfg(all(feature = "signature", feature = "secp256k1"))]
391impl<C> Debug for EcdsaKeyProvider<C>
392where
393 C: PrimeCurve + CurveArithmetic,
394 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C>,
395 SignatureSize<C>: ArrayLength<u8>,
396{
397 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
398 f.debug_struct("EcdsaKeyProvider")
399 .field("curve", &core::any::type_name::<C>())
400 .finish_non_exhaustive()
401 }
402}
403
404#[cfg(all(feature = "signature", feature = "secp256k1"))]
405impl<C> SigningKeyProvider for EcdsaKeyProvider<C>
406where
407 C: PrimeCurve + CurveArithmetic + DigestPrimitive + PointCompression + AssociatedOid + Send + Sync + 'static,
408 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C> + Reduce<C::Uint>,
409 SignatureSize<C>: ArrayLength<u8>,
410 FieldBytesSize<C>: ModulusSize,
411 AffinePoint<C>: VerifyPrimitive<C> + FromEncodedPoint<C> + ToEncodedPoint<C>,
412 SigningKey<C>: PrehashSigner<Signature<C>> + Keypair + Send + Sync + Debug,
413 <SigningKey<C> as Keypair>::VerifyingKey: EncodePublicKey,
414 Signature<C>: SignatureEncoding + SignatureAlgorithmIdentifier + Send + Sync,
415{
416 fn algorithm(&self) -> AlgorithmIdentifierOwned {
417 AlgorithmIdentifierOwned { oid: Signature::<C>::ALGORITHM_OID, parameters: None }
418 }
419
420 fn to_public_key_bytes(&self) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
421 let result = self
422 .signing_key
423 .verifying_key()
424 .to_public_key_der()
425 .map(|der| der.into_vec())
426 .map_err(KeyError::from);
427
428 Box::pin(async move { result })
429 }
430
431 fn sign_prehash(&self, prehash: &[u8]) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
432 let result = self
433 .signing_key
434 .sign_prehash(prehash)
435 .map(|signature: Signature<C>| signature.to_bytes().as_ref().to_vec())
436 .map_err(KeyError::from);
437
438 Box::pin(async move { result })
439 }
440
441 #[cfg(feature = "ecdh")]
442 fn key_agreement(
443 &self,
444 peer_public_key: &[u8],
445 ) -> Pin<Box<dyn Future<Output = Result<SecretSlice<u8>, KeyError>> + Send + '_>> {
446 let pk_result = PublicKey::<C>::from_sec1_bytes(peer_public_key);
447 let secret_key = *self.signing_key.as_nonzero_scalar();
448
449 Box::pin(async move {
450 let pk = pk_result?;
451 let shared_secret = diffie_hellman(secret_key, pk.as_affine());
452
453 Ok(SecretSlice::from(shared_secret.raw_secret_bytes().to_vec()))
454 })
455 }
456}
457
458#[cfg(all(feature = "signature", feature = "secp256k1"))]
459impl<C> SigningKeyProvider for Arc<EcdsaKeyProvider<C>>
460where
461 C: PrimeCurve + CurveArithmetic + DigestPrimitive + PointCompression + AssociatedOid + Send + Sync + 'static,
462 Scalar<C>: Invert<Output = CtOption<Scalar<C>>> + SignPrimitive<C> + Reduce<C::Uint>,
463 SignatureSize<C>: ArrayLength<u8>,
464 FieldBytesSize<C>: ModulusSize,
465 AffinePoint<C>: VerifyPrimitive<C> + FromEncodedPoint<C> + ToEncodedPoint<C>,
466 SigningKey<C>: PrehashSigner<Signature<C>> + Keypair + Send + Sync + Debug,
467 <SigningKey<C> as Keypair>::VerifyingKey: EncodePublicKey,
468 Signature<C>: SignatureEncoding + SignatureAlgorithmIdentifier + Send + Sync,
469{
470 fn algorithm(&self) -> AlgorithmIdentifierOwned {
471 self.as_ref().algorithm()
472 }
473
474 fn to_public_key_bytes(&self) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
475 self.as_ref().to_public_key_bytes()
476 }
477
478 fn sign_prehash(&self, prehash: &[u8]) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
479 self.as_ref().sign_prehash(prehash)
480 }
481
482 fn key_agreement(
483 &self,
484 peer_public_key: &[u8],
485 ) -> Pin<Box<dyn Future<Output = Result<SecretSlice<u8>, KeyError>> + Send + '_>> {
486 self.as_ref().key_agreement(peer_public_key)
487 }
488}
489
490#[cfg(feature = "signature")]
492pub type Secp256k1KeyProvider = EcdsaKeyProvider<Secp256k1>;
493
494#[cfg(feature = "aead")]
513pub trait EncryptingKeyProvider: Send + Sync + Debug {
514 fn algorithm(&self) -> AlgorithmIdentifierOwned;
516
517 fn encrypt(
529 &self,
530 nonce: &[u8],
531 plaintext: &[u8],
532 ) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>>;
533
534 fn decrypt(
545 &self,
546 nonce: &[u8],
547 ciphertext: &[u8],
548 ) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>>;
549}
550
551#[cfg(feature = "aead")]
570pub struct InMemoryEncryptingKeyProvider<A, O>
571where
572 A: Aead + Send + Sync + 'static,
573 O: AssociatedOid + Send + Sync,
574{
575 cipher: A,
576 _oid: PhantomData<O>,
577}
578
579#[cfg(feature = "aead")]
580impl<A, O> From<A> for InMemoryEncryptingKeyProvider<A, O>
581where
582 A: Aead + Send + Sync + 'static,
583 O: AssociatedOid + Send + Sync,
584{
585 fn from(cipher: A) -> Self {
586 InMemoryEncryptingKeyProvider { cipher, _oid: PhantomData }
587 }
588}
589
590#[cfg(feature = "aead")]
591impl<A, O> Debug for InMemoryEncryptingKeyProvider<A, O>
592where
593 A: Aead + Send + Sync + 'static,
594 O: AssociatedOid + Send + Sync,
595{
596 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
597 f.debug_struct("InMemoryEncryptingKeyProvider")
598 .field("algorithm", &O::OID)
599 .finish_non_exhaustive()
600 }
601}
602
603#[cfg(feature = "aead")]
604impl<A, O> EncryptingKeyProvider for InMemoryEncryptingKeyProvider<A, O>
605where
606 A: Aead + Send + Sync + 'static,
607 O: AssociatedOid + Send + Sync,
608{
609 fn algorithm(&self) -> AlgorithmIdentifierOwned {
610 AlgorithmIdentifierOwned { oid: O::OID, parameters: None }
611 }
612
613 fn encrypt(
614 &self,
615 nonce: &[u8],
616 plaintext: &[u8],
617 ) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
618 let nonce_size = <<A as AeadCore>::NonceSize as Unsigned>::USIZE;
619 let received_len = nonce.len();
620 if received_len != nonce_size {
621 return Box::pin(async move {
622 Err(KeyError::NonceLengthError(crate::error::ReceivedExpectedError::from((
623 received_len,
624 nonce_size,
625 ))))
626 });
627 }
628
629 let nonce_ref = Nonce::<A>::from_slice(nonce);
630 let result = self.cipher.encrypt(nonce_ref, plaintext).map_err(KeyError::from);
631 Box::pin(async move { result })
632 }
633
634 fn decrypt(
635 &self,
636 nonce: &[u8],
637 ciphertext: &[u8],
638 ) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
639 let nonce_size = <<A as AeadCore>::NonceSize as Unsigned>::USIZE;
640 let received_len = nonce.len();
641 if received_len != nonce_size {
642 return Box::pin(async move {
643 Err(KeyError::NonceLengthError(crate::error::ReceivedExpectedError::from((
644 received_len,
645 nonce_size,
646 ))))
647 });
648 }
649
650 let nonce_ref = Nonce::<A>::from_slice(nonce);
651 let result = self.cipher.decrypt(nonce_ref, ciphertext).map_err(KeyError::from);
652 Box::pin(async move { result })
653 }
654}
655
656#[cfg(feature = "aead")]
657impl<A, O> EncryptingKeyProvider for Arc<InMemoryEncryptingKeyProvider<A, O>>
658where
659 A: Aead + Send + Sync + 'static,
660 O: AssociatedOid + Send + Sync,
661{
662 fn algorithm(&self) -> AlgorithmIdentifierOwned {
663 self.as_ref().algorithm()
664 }
665
666 fn encrypt(
667 &self,
668 nonce: &[u8],
669 plaintext: &[u8],
670 ) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
671 self.as_ref().encrypt(nonce, plaintext)
672 }
673
674 fn decrypt(
675 &self,
676 nonce: &[u8],
677 ciphertext: &[u8],
678 ) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, KeyError>> + Send + '_>> {
679 self.as_ref().decrypt(nonce, ciphertext)
680 }
681}
682
683#[cfg(all(feature = "aead", feature = "aes-gcm"))]
688pub type Aes256GcmKeyProvider = InMemoryEncryptingKeyProvider<Aes256Gcm, Aes256GcmOid>;
690
691#[cfg(all(feature = "aead", feature = "aes-gcm"))]
692pub type Aes128GcmKeyProvider = InMemoryEncryptingKeyProvider<Aes128Gcm, Aes128GcmOid>;
694
695#[cfg(test)]
696mod tests {
697 use rand_core::OsRng;
698
699 use super::*;
700 use crate::crypto::hash::{Digest, Sha3_256};
701 use crate::crypto::secret::ToInsecure;
702 use crate::crypto::sign::ecdsa::k256::ecdsa::SigningKey;
703 use crate::crypto::sign::PrehashVerifier;
704
705 fn prehash(data: &[u8]) -> Vec<u8> {
706 let mut hasher = Sha3_256::new();
707 hasher.update(data);
708 hasher.finalize().to_vec()
709 }
710
711 #[tokio::test]
712 async fn test_secp256k1_provider_public_key() -> Result<(), Box<dyn std::error::Error>> {
713 let signing_key = SigningKey::random(&mut OsRng);
714 let provider = Secp256k1KeyProvider::from(signing_key);
715
716 let public_key_bytes = provider.to_public_key_bytes().await?;
717 assert_eq!(public_key_bytes.len(), 88);
719 Ok(())
720 }
721
722 #[tokio::test]
723 async fn test_secp256k1_provider_sign() -> Result<(), Box<dyn std::error::Error>> {
724 let signing_key = SigningKey::random(&mut OsRng);
725 let provider = Secp256k1KeyProvider::from(signing_key.clone());
726
727 let digest = prehash(b"test data to sign");
728 let signature_bytes = provider.sign_prehash(&digest).await?;
729
730 let signature = Secp256k1Signature::from_slice(&signature_bytes)?;
732 signing_key.verifying_key().verify_prehash(&digest, &signature)?;
733
734 Ok(())
735 }
736
737 #[tokio::test]
738 async fn test_secp256k1_provider_key_agreement() -> Result<(), Box<dyn std::error::Error>> {
739 let signing_key1 = SigningKey::random(&mut OsRng);
740 let signing_key2 = SigningKey::random(&mut OsRng);
741
742 let provider1 = Secp256k1KeyProvider::from(signing_key1.clone());
743 let provider2 = Secp256k1KeyProvider::from(signing_key2.clone());
744
745 let public1 = signing_key1.verifying_key().to_encoded_point(false).as_bytes().to_vec();
747 let public2 = signing_key2.verifying_key().to_encoded_point(false).as_bytes().to_vec();
748
749 let shared1 = provider1.key_agreement(&public2).await?.to_insecure()?;
751 let shared2 = provider2.key_agreement(&public1).await?.to_insecure()?;
752
753 assert_eq!(shared1, shared2);
754 assert_eq!(shared1.len(), 32); Ok(())
756 }
757
758 #[tokio::test]
759 async fn test_generic_provider_sign() -> Result<(), Box<dyn std::error::Error>> {
760 let signing_key = SigningKey::random(&mut OsRng);
761 let provider: Secp256k1Provider = InMemorySigningKeyProvider::from(signing_key.clone());
762
763 let digest = prehash(b"test data to sign");
764 let signature_bytes = provider.sign_prehash(&digest).await?;
765
766 let signature = Secp256k1Signature::from_slice(&signature_bytes)?;
768 signing_key.verifying_key().verify_prehash(&digest, &signature)?;
769
770 Ok(())
771 }
772
773 #[tokio::test]
774 async fn test_arc_secp256k1_provider() -> Result<(), Box<dyn std::error::Error>> {
775 let signing_key = SigningKey::random(&mut OsRng);
776 let provider = Arc::new(Secp256k1KeyProvider::from(signing_key.clone()));
777
778 let public_key_bytes = provider.to_public_key_bytes().await?;
780 assert_eq!(public_key_bytes.len(), 88);
782
783 let digest = prehash(b"test");
784 let signature_bytes = provider.sign_prehash(&digest).await?;
785
786 let signature = Secp256k1Signature::from_slice(&signature_bytes)?;
787 signing_key.verifying_key().verify_prehash(&digest, &signature)?;
788
789 Ok(())
790 }
791
792 #[tokio::test]
793 async fn test_algorithm_identifier() -> Result<(), Box<dyn std::error::Error>> {
794 let signing_key = SigningKey::random(&mut OsRng);
795 let provider = Secp256k1KeyProvider::from(signing_key);
796
797 let alg = provider.algorithm();
798 assert_eq!(alg.oid, Secp256k1Signature::ALGORITHM_OID);
799 Ok(())
800 }
801}