Skip to main content

crypto_seal/
key.rs

1use crate::{Result, error::Error};
2#[cfg(feature = "std")]
3use aes_gcm::aead::stream::{DecryptorBE32, EncryptorBE32};
4use aes_gcm::{
5    Aes256Gcm, Key, KeyInit, Nonce,
6    aead::{Aead, Payload},
7};
8use alloc::string::String;
9use alloc::vec::Vec;
10use core::hash::Hash;
11use curve25519_dalek::edwards::CompressedEdwardsY;
12use ed25519_dalek::{Signature, SigningKey};
13use hkdf::Hkdf;
14use hmac::{Hmac, Mac};
15use rand::RngCore;
16use rand::rngs::OsRng;
17use serde::{Deserialize, Deserializer, Serialize};
18use sha2::Digest;
19use sha2::Sha256;
20use sha2::Sha512;
21use signature::{Signer as _, Verifier as _};
22#[cfg(feature = "std")]
23use std::io;
24use zeroize::{Zeroize, Zeroizing};
25
26type HmacSha256 = Hmac<Sha256>;
27
28/// Container of private keys
29///
30/// The following is supported
31///
32/// - [`ed25519_dalek`]
33/// - [`k256`]
34/// - [`p256`]
35/// - [`p384`]
36/// - [`aes_gcm::Aes256Gcm`]
37#[derive(Clone)]
38pub enum PrivateKey {
39    Ed25519(ed25519_dalek::SigningKey),
40    Secp256k1(k256::ecdsa::SigningKey),
41    P256(p256::ecdsa::SigningKey),
42    P384(p384::ecdsa::SigningKey),
43    Aes256([u8; 32]),
44}
45
46impl core::fmt::Debug for PrivateKey {
47    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
48        let ty = match self {
49            PrivateKey::Ed25519(_) => "ed25519",
50            PrivateKey::Secp256k1(_) => "secp256k1",
51            PrivateKey::P256(_) => "p256",
52            PrivateKey::P384(_) => "p384",
53            PrivateKey::Aes256(_) => "aes256",
54        };
55
56        write!(f, "{ty}")
57    }
58}
59
60impl Default for PrivateKey {
61    fn default() -> Self {
62        Self::new_with(PrivateKeyType::default())
63    }
64}
65
66impl Zeroize for PrivateKey {
67    fn zeroize(&mut self) {
68        match self {
69            PrivateKey::Ed25519(key) => *key = SigningKey::from_bytes(&[0u8; 32]),
70            PrivateKey::Secp256k1(key) => {
71                if let Ok(dummy) = k256::ecdsa::SigningKey::from_slice(&[1u8; 32]) {
72                    *key = dummy
73                }
74            }
75            PrivateKey::P256(key) => {
76                if let Ok(dummy) = p256::ecdsa::SigningKey::from_slice(&[1u8; 32]) {
77                    *key = dummy
78                }
79            }
80            PrivateKey::P384(key) => {
81                if let Ok(dummy) = p384::ecdsa::SigningKey::from_slice(&[1u8; 48]) {
82                    *key = dummy
83                }
84            }
85            PrivateKey::Aes256(key) => key.zeroize(),
86        }
87    }
88}
89
90impl Drop for PrivateKey {
91    fn drop(&mut self) {
92        self.zeroize()
93    }
94}
95
96/// Container of public keys
97///
98/// The following is supported
99///
100/// - [`ed25519_dalek`]
101/// - [`k256`]
102/// - [`p256`]
103/// - [`p384`]
104#[derive(Clone, Copy)]
105pub enum PublicKey {
106    Ed25519(ed25519_dalek::VerifyingKey),
107    Secp256k1(k256::ecdsa::VerifyingKey),
108    P256(p256::ecdsa::VerifyingKey),
109    P384(p384::ecdsa::VerifyingKey),
110}
111
112impl PartialEq for PublicKey {
113    fn eq(&self, other: &Self) -> bool {
114        self.encode() == other.encode()
115    }
116}
117
118impl Eq for PublicKey {}
119
120impl Hash for PublicKey {
121    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
122        self.encode().hash(state);
123    }
124}
125
126impl PartialOrd for PublicKey {
127    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
128        Some(self.cmp(other))
129    }
130}
131
132impl Ord for PublicKey {
133    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
134        self.encode().cmp(&other.encode())
135    }
136}
137
138impl core::fmt::Debug for PublicKey {
139    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
140        write!(f, "{}", self)
141    }
142}
143
144impl core::fmt::Display for PublicKey {
145    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
146        write!(f, "{}", bs58::encode(self.encode()).into_string())
147    }
148}
149
150impl Serialize for PublicKey {
151    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
152    where
153        S: serde::Serializer,
154    {
155        let pk_str = bs58::encode(self.encode()).into_string();
156        serializer.serialize_str(&pk_str)
157    }
158}
159
160impl<'d> Deserialize<'d> for PublicKey {
161    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
162    where
163        D: Deserializer<'d>,
164    {
165        let pk_str = <String>::deserialize(deserializer)?;
166        let bytes = bs58::decode(pk_str)
167            .into_vec()
168            .map_err(serde::de::Error::custom)?;
169        PublicKey::decode(&bytes).map_err(serde::de::Error::custom)
170    }
171}
172
173#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
174pub enum PublicKeyType {
175    /// Ed25519 Public Key
176    Ed25519,
177
178    /// Secp256k1 Public Key
179    Secp256k1,
180
181    /// NIST P-256 Public Key
182    P256,
183
184    /// NIST P-384 Public Key
185    P384,
186}
187
188impl TryFrom<u8> for PublicKeyType {
189    type Error = Error;
190    fn try_from(value: u8) -> core::result::Result<Self, Self::Error> {
191        match value {
192            0xa1 => Ok(PublicKeyType::Ed25519),
193            0xb1 => Ok(PublicKeyType::Secp256k1),
194            0xd1 => Ok(PublicKeyType::P256),
195            0xe1 => Ok(PublicKeyType::P384),
196            _ => Err(Error::InvalidPublicKey),
197        }
198    }
199}
200
201impl From<PublicKeyType> for u8 {
202    fn from(value: PublicKeyType) -> Self {
203        match value {
204            PublicKeyType::Ed25519 => 0xa1,
205            PublicKeyType::Secp256k1 => 0xb1,
206            PublicKeyType::P256 => 0xd1,
207            PublicKeyType::P384 => 0xe1,
208        }
209    }
210}
211
212impl From<ed25519_dalek::VerifyingKey> for PublicKey {
213    fn from(pk: ed25519_dalek::VerifyingKey) -> Self {
214        PublicKey::Ed25519(pk)
215    }
216}
217
218impl TryFrom<PublicKey> for k256::ecdsa::VerifyingKey {
219    type Error = Error;
220
221    fn try_from(value: PublicKey) -> core::result::Result<Self, Self::Error> {
222        match value {
223            PublicKey::Secp256k1(pk) => Ok(pk),
224            _ => Err(Error::InvalidPublicKey),
225        }
226    }
227}
228
229impl TryFrom<PublicKey> for p256::ecdsa::VerifyingKey {
230    type Error = Error;
231
232    fn try_from(value: PublicKey) -> core::result::Result<Self, Self::Error> {
233        match value {
234            PublicKey::P256(pk) => Ok(pk),
235            _ => Err(Error::InvalidPublicKey),
236        }
237    }
238}
239
240impl TryFrom<PublicKey> for p384::ecdsa::VerifyingKey {
241    type Error = Error;
242
243    fn try_from(value: PublicKey) -> core::result::Result<Self, Self::Error> {
244        match value {
245            PublicKey::P384(pk) => Ok(pk),
246            _ => Err(Error::InvalidPublicKey),
247        }
248    }
249}
250
251impl TryFrom<&PrivateKey> for x25519_dalek::StaticSecret {
252    type Error = Error;
253
254    fn try_from(value: &PrivateKey) -> core::result::Result<Self, Self::Error> {
255        match value {
256            PrivateKey::Ed25519(kp) => {
257                let mut hasher: Sha512 = Sha512::new();
258                hasher.update(kp.as_bytes());
259                let hash = hasher.finalize();
260                let mut new_sk: [u8; 32] = [0; 32];
261                new_sk.copy_from_slice(&hash[..32]);
262                let sk = x25519_dalek::StaticSecret::from(new_sk);
263                new_sk.zeroize();
264                Ok(sk)
265            }
266            _ => Err(Error::Unsupported),
267        }
268    }
269}
270
271impl TryFrom<PrivateKey> for x25519_dalek::StaticSecret {
272    type Error = Error;
273
274    fn try_from(value: PrivateKey) -> core::result::Result<Self, Self::Error> {
275        TryFrom::try_from(&value)
276    }
277}
278
279impl TryFrom<PublicKey> for ed25519_dalek::VerifyingKey {
280    type Error = Error;
281
282    fn try_from(value: PublicKey) -> core::result::Result<Self, Self::Error> {
283        match value {
284            PublicKey::Ed25519(pk) => Ok(pk),
285            _ => Err(Error::InvalidPublicKey),
286        }
287    }
288}
289
290impl TryFrom<PublicKey> for x25519_dalek::PublicKey {
291    type Error = Error;
292
293    fn try_from(value: PublicKey) -> core::result::Result<Self, Self::Error> {
294        match value {
295            PublicKey::Ed25519(pk) => {
296                let ep = CompressedEdwardsY(pk.to_bytes())
297                    .decompress()
298                    .ok_or(Error::Unsupported)?; //Note: This should not error here
299                let mon = ep.to_montgomery();
300                Ok(x25519_dalek::PublicKey::from(mon.0))
301            }
302            _ => Err(Error::InvalidPublicKey),
303        }
304    }
305}
306
307impl PublicKey {
308    pub fn from_bytes(key_type: PublicKeyType, bytes: &[u8]) -> Result<PublicKey> {
309        match key_type {
310            PublicKeyType::Ed25519 => {
311                let bytes: [u8; 32] = bytes.try_into()?;
312                Self::from_ed25519_bytes(&bytes)
313            }
314            PublicKeyType::Secp256k1 => Self::from_secp256k1_bytes(bytes),
315            PublicKeyType::P256 => Ok(PublicKey::P256(p256::ecdsa::VerifyingKey::from_sec1_bytes(
316                bytes,
317            )?)),
318            PublicKeyType::P384 => Ok(PublicKey::P384(p384::ecdsa::VerifyingKey::from_sec1_bytes(
319                bytes,
320            )?)),
321        }
322    }
323
324    pub fn from_ed25519_bytes(bytes: &[u8; 32]) -> Result<PublicKey> {
325        let pk = ed25519_dalek::VerifyingKey::from_bytes(bytes)?;
326        Ok(PublicKey::Ed25519(pk))
327    }
328
329    pub fn from_secp256k1_bytes(bytes: &[u8]) -> Result<PublicKey> {
330        let public_key = k256::ecdsa::VerifyingKey::from_sec1_bytes(bytes)?;
331        Ok(PublicKey::Secp256k1(public_key))
332    }
333
334    pub fn decode(bytes: &[u8]) -> Result<PublicKey> {
335        let (ktype, key) = bytes.split_first().ok_or(Error::InvalidPublicKey)?;
336        Self::from_bytes((*ktype).try_into()?, key)
337    }
338
339    pub fn encode(&self) -> Vec<u8> {
340        let mut data = Vec::new();
341        data.push(self.key_type().into());
342        data.extend(self.to_bytes());
343        data
344    }
345
346    /// Convert the [`PublicKey`] to a byte array
347    pub fn to_bytes(&self) -> Vec<u8> {
348        match self {
349            PublicKey::Ed25519(public_key) => public_key.to_bytes().to_vec(),
350            PublicKey::Secp256k1(public_key) => {
351                public_key.to_encoded_point(true).as_bytes().to_vec()
352            }
353            PublicKey::P256(public_key) => public_key.to_encoded_point(true).as_bytes().to_vec(),
354            PublicKey::P384(public_key) => public_key.to_encoded_point(true).as_bytes().to_vec(),
355        }
356    }
357
358    pub fn key_type(&self) -> PublicKeyType {
359        match self {
360            PublicKey::Ed25519(_) => PublicKeyType::Ed25519,
361            PublicKey::Secp256k1(_) => PublicKeyType::Secp256k1,
362            PublicKey::P256(_) => PublicKeyType::P256,
363            PublicKey::P384(_) => PublicKeyType::P384,
364        }
365    }
366}
367
368impl PublicKey {
369    /// Verify the signature of the data provided using [`PrivateKey`]
370    pub fn verify(&self, data: &[u8], signature: &[u8]) -> Result<()> {
371        match self {
372            PublicKey::Ed25519(pubkey) => {
373                let signature = Signature::from_bytes(signature.try_into()?);
374                pubkey.verify(data, &signature)?;
375                Ok(())
376            }
377            PublicKey::Secp256k1(pubkey) => {
378                let sig = k256::ecdsa::Signature::from_slice(signature)?;
379                pubkey.verify(data, &sig)?;
380                Ok(())
381            }
382            PublicKey::P256(pubkey) => {
383                let sig = p256::ecdsa::Signature::from_slice(signature)?;
384                pubkey.verify(data, &sig)?;
385                Ok(())
386            }
387            PublicKey::P384(pubkey) => {
388                let sig = p384::ecdsa::Signature::from_slice(signature)?;
389                pubkey.verify(data, &sig)?;
390                Ok(())
391            }
392        }
393    }
394}
395
396#[cfg(feature = "std")]
397#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
398impl PublicKey {
399    /// Verify the signature of the data from [`std::io::Read`] using [`PrivateKey`]
400    pub fn verify_reader(&self, reader: &mut impl io::Read, signature: &[u8]) -> Result<()> {
401        let mut data = Vec::new();
402        reader.read_to_end(&mut data)?;
403        self.verify(&data, signature)
404    }
405}
406/// [`PrivateKey`] Types
407#[derive(Debug, Copy, Clone, Default)]
408pub enum PrivateKeyType {
409    /// ED25519 Private Key
410    #[default]
411    Ed25519,
412
413    /// AES-256 Private Key
414    Aes256,
415
416    /// Secp256k1 Private Key
417    Secp256k1,
418
419    /// NIST P-256 Private Key
420    P256,
421
422    /// NIST P-384 Private Key
423    P384,
424}
425
426#[cfg(feature = "std")]
427const WRITE_BUFFER_SIZE: usize = 512;
428#[cfg(feature = "std")]
429const READ_BUFFER_SIZE: usize = 528;
430const NONCE_LEN: usize = 12;
431const SALT_LEN: usize = 16;
432const ENCRYPT_INFO: &[u8] = b"crypto-seal:aes256-gcm:v1";
433#[cfg(feature = "std")]
434const ENCRYPT_STREAM_INFO: &[u8] = b"crypto-seal:aes256-gcm-stream:v1";
435const MAC_INFO: &[u8] = b"crypto-seal:hmac-sha256:v1";
436
437impl TryFrom<u8> for PrivateKeyType {
438    type Error = Error;
439    fn try_from(value: u8) -> core::result::Result<Self, Self::Error> {
440        match value {
441            0xa1 => Ok(PrivateKeyType::Ed25519),
442            0xb1 => Ok(PrivateKeyType::Secp256k1),
443            0xc1 => Ok(PrivateKeyType::Aes256),
444            0xd1 => Ok(PrivateKeyType::P256),
445            0xe1 => Ok(PrivateKeyType::P384),
446            _ => Err(Error::InvalidPrivateKey),
447        }
448    }
449}
450
451impl From<PrivateKeyType> for u8 {
452    fn from(value: PrivateKeyType) -> Self {
453        match value {
454            PrivateKeyType::Ed25519 => 0xa1,
455            PrivateKeyType::Secp256k1 => 0xb1,
456            PrivateKeyType::Aes256 => 0xc1,
457            PrivateKeyType::P256 => 0xd1,
458            PrivateKeyType::P384 => 0xe1,
459        }
460    }
461}
462
463impl PrivateKey {
464    /// Generates a new [`PrivateKey`] with randomly generated key
465    pub fn new() -> Self {
466        Self::default()
467    }
468
469    /// Generate a [`PrivateKey`] using [`PrivateKeyType`]
470    pub fn new_with(key_type: PrivateKeyType) -> Self {
471        match key_type {
472            PrivateKeyType::Ed25519 => PrivateKey::Ed25519(SigningKey::generate(&mut OsRng)),
473            PrivateKeyType::Aes256 => {
474                let key_sized = generate::<32>();
475                PrivateKey::Aes256(key_sized)
476            }
477            PrivateKeyType::Secp256k1 => {
478                PrivateKey::Secp256k1(k256::ecdsa::SigningKey::random(&mut OsRng))
479            }
480            PrivateKeyType::P256 => PrivateKey::P256(p256::ecdsa::SigningKey::random(&mut OsRng)),
481            PrivateKeyType::P384 => PrivateKey::P384(p384::ecdsa::SigningKey::random(&mut OsRng)),
482        }
483    }
484
485    /// Import private key which is identified with [`PrivateKeyType`]
486    pub fn import(key_type: PrivateKeyType, key: Vec<u8>) -> Result<Self> {
487        let key = zeroize::Zeroizing::new(key);
488        match key_type {
489            PrivateKeyType::Ed25519 => {
490                let key: [u8; 32] = key.as_slice().try_into()?;
491                Ok(PrivateKey::Ed25519(ed25519_dalek::SigningKey::from_bytes(
492                    &key,
493                )))
494            }
495            PrivateKeyType::Aes256 => key
496                .as_slice()
497                .try_into()
498                .map(PrivateKey::Aes256)
499                .map_err(Error::from),
500            PrivateKeyType::Secp256k1 => k256::ecdsa::SigningKey::from_slice(&key)
501                .map(PrivateKey::Secp256k1)
502                .map_err(Error::from),
503            PrivateKeyType::P256 => p256::ecdsa::SigningKey::from_slice(&key)
504                .map(PrivateKey::P256)
505                .map_err(Error::from),
506            PrivateKeyType::P384 => p384::ecdsa::SigningKey::from_slice(&key)
507                .map(PrivateKey::P384)
508                .map_err(Error::from),
509        }
510    }
511
512    /// Imports a private key from bytes prefixed with a [`PrivateKeyType`] identifier
513    pub fn decode<B: AsRef<[u8]>>(bytes: B) -> Result<PrivateKey> {
514        let (ktype, key) = bytes
515            .as_ref()
516            .split_first()
517            .ok_or(Error::InvalidPrivateKey)?;
518        Self::import((*ktype).try_into()?, key.to_vec())
519    }
520
521    /// Exports the keys out as bytes.
522    pub fn to_bytes(&self) -> Vec<u8> {
523        match self {
524            PrivateKey::Ed25519(kp) => kp.to_bytes().to_vec(),
525            PrivateKey::Secp256k1(sk) => sk.to_bytes().as_slice().to_vec(),
526            PrivateKey::P256(sk) => sk.to_bytes().as_slice().to_vec(),
527            PrivateKey::P384(sk) => sk.to_bytes().as_slice().to_vec(),
528            PrivateKey::Aes256(key) => key.to_vec(),
529        }
530    }
531
532    /// Exports the key out with an identifier
533    pub fn encode(&self) -> Vec<u8> {
534        let mut data = Vec::new();
535        data.push(self.key_type().into());
536        data.extend(self.to_bytes());
537        data
538    }
539
540    /// Provides the [`PrivateKeyType`] of the [`PrivateKey`]
541    pub fn key_type(&self) -> PrivateKeyType {
542        match self {
543            PrivateKey::Aes256(_) => PrivateKeyType::Aes256,
544            PrivateKey::Ed25519(_) => PrivateKeyType::Ed25519,
545            PrivateKey::Secp256k1(_) => PrivateKeyType::Secp256k1,
546            PrivateKey::P256(_) => PrivateKeyType::P256,
547            PrivateKey::P384(_) => PrivateKeyType::P384,
548        }
549    }
550
551    /// Provides the [`PublicKey`] of the [`PrivateKey`]
552    /// Note: This will only work with asymmetric keys. Any symmetric keys will
553    ///       return [`Error::Unsupported`]
554    pub fn public_key(&self) -> Result<PublicKey> {
555        match self {
556            PrivateKey::Aes256(_) => Err(Error::Unsupported),
557            PrivateKey::Ed25519(key) => Ok(key.verifying_key().into()),
558            PrivateKey::Secp256k1(key) => Ok(PublicKey::Secp256k1(*key.verifying_key())),
559            PrivateKey::P256(key) => Ok(PublicKey::P256(*key.verifying_key())),
560            PrivateKey::P384(key) => Ok(PublicKey::P384(*key.verifying_key())),
561        }
562    }
563
564    /// Sign the data provided using [`PrivateKey`]
565    pub fn sign<B: AsRef<[u8]>>(&self, data: B) -> Result<Vec<u8>> {
566        let data = data.as_ref();
567        match self {
568            PrivateKey::Aes256(key) => {
569                let mac_key = derive_key(key, &[], MAC_INFO)?;
570                let mut mac = <HmacSha256 as Mac>::new_from_slice(&*mac_key)
571                    .map_err(|_| Error::EncryptionError)?;
572                mac.update(data);
573                Ok(mac.finalize().into_bytes().to_vec())
574            }
575            PrivateKey::Ed25519(key) => {
576                let signature = key.sign(data);
577                Ok(signature.to_bytes().to_vec())
578            }
579            PrivateKey::Secp256k1(key) => {
580                let signature: k256::ecdsa::Signature = key.try_sign(data)?;
581                Ok(signature.to_vec())
582            }
583            PrivateKey::P256(key) => {
584                let signature: p256::ecdsa::Signature = key.try_sign(data)?;
585                Ok(signature.to_vec())
586            }
587            PrivateKey::P384(key) => {
588                let signature: p384::ecdsa::Signature = key.try_sign(data)?;
589                Ok(signature.to_vec())
590            }
591        }
592    }
593
594    /// Sign the data from [`std::io::Read`] using [`PrivateKey`]
595    #[cfg(feature = "std")]
596    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
597    pub fn sign_reader(&self, reader: &mut impl io::Read) -> Result<Vec<u8>> {
598        match self {
599            PrivateKey::Aes256(key) => {
600                let mac_key = derive_key(key, &[], MAC_INFO)?;
601                let mut mac = <HmacSha256 as Mac>::new_from_slice(&*mac_key)
602                    .map_err(|_| Error::EncryptionError)?;
603                let mut buffer = [0u8; WRITE_BUFFER_SIZE];
604                loop {
605                    match reader.read(&mut buffer) {
606                        Ok(0) => break,
607                        Ok(n) => mac.update(&buffer[..n]),
608                        Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
609                        Err(e) => return Err(Error::from(e)),
610                    }
611                }
612                Ok(mac.finalize().into_bytes().to_vec())
613            }
614            _ => {
615                let mut data = Vec::new();
616                reader.read_to_end(&mut data)?;
617                self.sign(&data)
618            }
619        }
620    }
621
622    /// Verify the signature of the data provided using [`PrivateKey`]
623    pub fn verify(&self, data: &[u8], signature: &[u8]) -> Result<()> {
624        match self {
625            PrivateKey::Aes256(key) => {
626                let mac_key = derive_key(key, &[], MAC_INFO)?;
627                let mut mac = <HmacSha256 as Mac>::new_from_slice(&*mac_key)
628                    .map_err(|_| Error::InvalidSignature)?;
629                mac.update(data);
630                mac.verify_slice(signature)
631                    .map_err(|_| Error::InvalidSignature)
632            }
633            _ => {
634                let public_key = self.public_key()?;
635                public_key.verify(data, signature)
636            }
637        }
638    }
639
640    /// Verify the signature of the data from [`std::io::Read`] using [`PrivateKey`]
641    #[cfg(feature = "std")]
642    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
643    pub fn verify_reader(&self, reader: &mut impl io::Read, signature: &[u8]) -> Result<()> {
644        match self {
645            PrivateKey::Aes256(key) => {
646                let mac_key = derive_key(key, &[], MAC_INFO)?;
647                let mut mac = <HmacSha256 as Mac>::new_from_slice(&*mac_key)
648                    .map_err(|_| Error::InvalidSignature)?;
649                let mut buffer = [0u8; WRITE_BUFFER_SIZE];
650                loop {
651                    match reader.read(&mut buffer) {
652                        Ok(0) => break,
653                        Ok(n) => mac.update(&buffer[..n]),
654                        Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
655                        Err(e) => return Err(Error::from(e)),
656                    }
657                }
658                mac.verify_slice(signature)
659                    .map_err(|_| Error::InvalidSignature)
660            }
661            _ => {
662                let public_key = self.public_key()?;
663                public_key.verify_reader(reader, signature)
664            }
665        }
666    }
667}
668
669#[derive(Default, Copy, Clone, PartialEq)]
670pub enum CarrierKeyType {
671    /// Use AES256 key
672    Direct { key: [u8; 32] },
673
674    /// Use key exchange to generate a shared key
675    Exchange { public_key: PublicKey },
676
677    /// Use own private key
678    /// > **Note** If public key encryption is used, this will use your own private/public key for key exchange
679    /// > otherwise if its AES256, it will encrypt with that key itself
680    #[default]
681    None,
682}
683
684impl PrivateKey {
685    /// Encrypt the data using [`PrivateKey`].
686    /// If [`PrivateKeyType::Aes256`] is used, the `pubkey` will be ignored
687    pub fn encrypt(&self, data: &[u8], pubkey: CarrierKeyType) -> Result<Vec<u8>> {
688        self.encrypt_with_aad(data, pubkey, &[])
689    }
690
691    pub fn encrypt_with_aad(
692        &self,
693        data: &[u8],
694        pubkey: CarrierKeyType,
695        aad: &[u8],
696    ) -> Result<Vec<u8>> {
697        let ikm = self.fetch_encryption_key(pubkey)?;
698        let salt = generate::<SALT_LEN>();
699        let key = derive_key(ikm.as_slice(), &salt, ENCRYPT_INFO)?;
700        let raw_nonce = generate::<NONCE_LEN>();
701        let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(&*key));
702        let nonce = Nonce::from_slice(&raw_nonce);
703        let mut out = cipher
704            .encrypt(nonce, Payload { msg: data, aad })
705            .map_err(|_| Error::EncryptionError)?;
706        out.extend_from_slice(&salt);
707        out.extend_from_slice(&raw_nonce);
708        Ok(out)
709    }
710
711    /// Decrypt the data using [`PrivateKey`].
712    /// If [`PrivateKeyType::Aes256`] is used, the `pubkey` will be ignored
713    pub fn decrypt(&self, data: &[u8], pubkey: CarrierKeyType) -> Result<Vec<u8>> {
714        self.decrypt_with_aad(data, pubkey, &[])
715    }
716
717    pub fn decrypt_with_aad(
718        &self,
719        data: &[u8],
720        pubkey: CarrierKeyType,
721        aad: &[u8],
722    ) -> Result<Vec<u8>> {
723        if data.len() < SALT_LEN + NONCE_LEN {
724            return Err(Error::DecryptionError);
725        }
726        let ikm = self.fetch_encryption_key(pubkey)?;
727        let (rest, raw_nonce) = data.split_at(data.len() - NONCE_LEN);
728        let (ciphertext, salt) = rest.split_at(rest.len() - SALT_LEN);
729        let key = derive_key(ikm.as_slice(), salt, ENCRYPT_INFO)?;
730        let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(&*key));
731        let nonce = Nonce::from_slice(raw_nonce);
732        cipher
733            .decrypt(
734                nonce,
735                Payload {
736                    msg: ciphertext,
737                    aad,
738                },
739            )
740            .map_err(|_| Error::DecryptionError)
741    }
742}
743
744impl PrivateKey {
745    /// Encrypt the data stream from [`std::io::Read`] to [`std::io::Write`] using [`PrivateKey`].
746    /// If [`PrivateKeyType::Aes256`] is used, the `pubkey` will be ignored
747    #[cfg(feature = "std")]
748    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
749    pub fn encrypt_stream(
750        &self,
751        reader: &mut impl io::Read,
752        writer: &mut impl io::Write,
753        pubkey: CarrierKeyType,
754    ) -> Result<()> {
755        let ikm = self.fetch_encryption_key(pubkey)?;
756        let salt = generate::<SALT_LEN>();
757        let key = derive_key(ikm.as_slice(), &salt, ENCRYPT_STREAM_INFO)?;
758        let nonce = generate::<7>();
759
760        let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(&*key));
761        let mut buffer = [0u8; WRITE_BUFFER_SIZE];
762        let mut stream = EncryptorBE32::from_aead(cipher, nonce.as_slice().into());
763        writer.write_all(&salt)?;
764        writer.write_all(&nonce)?;
765        loop {
766            let read_count = fill(reader, &mut buffer)?;
767            if read_count == WRITE_BUFFER_SIZE {
768                let ciphertext = stream
769                    .encrypt_next(buffer.as_slice())
770                    .map_err(|_| Error::EncryptionStreamError)?;
771                writer.write_all(&ciphertext)?;
772            } else {
773                let ciphertext = stream
774                    .encrypt_last(&buffer[..read_count])
775                    .map_err(|_| Error::EncryptionStreamError)?;
776                writer.write_all(&ciphertext)?;
777                break;
778            }
779        }
780        Ok(())
781    }
782
783    /// Decrypt the data stream from [`std::io::Read`] to [`std::io::Write`] using [`PrivateKey`].
784    /// If [`PrivateKeyType::Aes256`] is used, the `pubkey` will be ignored
785    #[cfg(feature = "std")]
786    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
787    pub fn decrypt_stream(
788        &self,
789        reader: &mut impl io::Read,
790        writer: &mut impl io::Write,
791        pubkey: CarrierKeyType,
792    ) -> Result<()> {
793        let ikm = self.fetch_encryption_key(pubkey)?;
794        let mut salt = [0u8; SALT_LEN];
795        reader.read_exact(&mut salt)?;
796        let key = derive_key(ikm.as_slice(), &salt, ENCRYPT_STREAM_INFO)?;
797        let mut nonce = vec![0u8; 7];
798        reader.read_exact(&mut nonce)?;
799
800        let cipher = Aes256Gcm::new(Key::<Aes256Gcm>::from_slice(&*key));
801
802        let mut stream = DecryptorBE32::from_aead(cipher, nonce.as_slice().into());
803        let mut buffer = [0u8; READ_BUFFER_SIZE];
804        loop {
805            let read_count = fill(reader, &mut buffer)?;
806            if read_count == READ_BUFFER_SIZE {
807                let plaintext = stream
808                    .decrypt_next(buffer.as_slice())
809                    .map_err(|_| Error::DecryptionStreamError)?;
810                writer.write_all(&plaintext)?;
811            } else {
812                let plaintext = stream
813                    .decrypt_last(&buffer[..read_count])
814                    .map_err(|_| Error::DecryptionStreamError)?;
815                writer.write_all(&plaintext)?;
816                break;
817            }
818        }
819        writer.flush()?;
820        Ok(())
821    }
822
823    /// Used internally to obtain the encryption key
824    fn fetch_encryption_key(&self, pubkey: CarrierKeyType) -> Result<Zeroizing<Vec<u8>>> {
825        match pubkey {
826            CarrierKeyType::Direct { key } => Ok(Zeroizing::new(key.to_vec())),
827            CarrierKeyType::Exchange { public_key } => match self {
828                PrivateKey::Aes256(key) => Ok(Zeroizing::new(key.to_vec())),
829                PrivateKey::Secp256k1(sk) => {
830                    let peer: k256::ecdsa::VerifyingKey = public_key.try_into()?;
831                    let shared =
832                        k256::ecdh::diffie_hellman(sk.as_nonzero_scalar(), peer.as_affine());
833                    Ok(Zeroizing::new(
834                        shared.raw_secret_bytes().as_slice().to_vec(),
835                    ))
836                }
837                PrivateKey::Ed25519(_) => {
838                    let static_key: x25519_dalek::StaticSecret = self.try_into()?;
839                    let public_key: x25519_dalek::PublicKey = public_key.try_into()?;
840
841                    let enc_key = static_key.diffie_hellman(&public_key);
842                    Ok(Zeroizing::new(enc_key.as_bytes().to_vec()))
843                }
844                PrivateKey::P256(sk) => {
845                    let peer: p256::ecdsa::VerifyingKey = public_key.try_into()?;
846                    let shared =
847                        p256::ecdh::diffie_hellman(sk.as_nonzero_scalar(), peer.as_affine());
848                    Ok(Zeroizing::new(
849                        shared.raw_secret_bytes().as_slice().to_vec(),
850                    ))
851                }
852                PrivateKey::P384(sk) => {
853                    let peer: p384::ecdsa::VerifyingKey = public_key.try_into()?;
854                    let shared =
855                        p384::ecdh::diffie_hellman(sk.as_nonzero_scalar(), peer.as_affine());
856                    Ok(Zeroizing::new(
857                        shared.raw_secret_bytes().as_slice().to_vec(),
858                    ))
859                }
860            },
861            CarrierKeyType::None => match self {
862                PrivateKey::Aes256(key) => Ok(Zeroizing::new(key.to_vec())),
863                PrivateKey::Secp256k1(sk) => {
864                    let shared = k256::ecdh::diffie_hellman(
865                        sk.as_nonzero_scalar(),
866                        sk.verifying_key().as_affine(),
867                    );
868                    Ok(Zeroizing::new(
869                        shared.raw_secret_bytes().as_slice().to_vec(),
870                    ))
871                }
872                PrivateKey::Ed25519(_) => {
873                    let static_key: x25519_dalek::StaticSecret = self.try_into()?;
874                    let public_key: x25519_dalek::PublicKey =
875                        x25519_dalek::PublicKey::from(&static_key);
876                    let enc_key = static_key.diffie_hellman(&public_key);
877                    Ok(Zeroizing::new(enc_key.as_bytes().to_vec()))
878                }
879                PrivateKey::P256(sk) => {
880                    let shared = p256::ecdh::diffie_hellman(
881                        sk.as_nonzero_scalar(),
882                        sk.verifying_key().as_affine(),
883                    );
884                    Ok(Zeroizing::new(
885                        shared.raw_secret_bytes().as_slice().to_vec(),
886                    ))
887                }
888                PrivateKey::P384(sk) => {
889                    let shared = p384::ecdh::diffie_hellman(
890                        sk.as_nonzero_scalar(),
891                        sk.verifying_key().as_affine(),
892                    );
893                    Ok(Zeroizing::new(
894                        shared.raw_secret_bytes().as_slice().to_vec(),
895                    ))
896                }
897            },
898        }
899    }
900}
901
902#[cfg(feature = "std")]
903fn fill(reader: &mut impl io::Read, buffer: &mut [u8]) -> io::Result<usize> {
904    let mut filled = 0;
905    while filled < buffer.len() {
906        match reader.read(&mut buffer[filled..]) {
907            Ok(0) => break,
908            Ok(n) => filled += n,
909            Err(e) if e.kind() == io::ErrorKind::Interrupted => continue,
910            Err(e) => return Err(e),
911        }
912    }
913    Ok(filled)
914}
915
916fn derive_key(ikm: &[u8], salt: &[u8], info: &[u8]) -> Result<Zeroizing<[u8; 32]>> {
917    let mut okm = Zeroizing::new([0u8; 32]);
918    Hkdf::<Sha256>::new(Some(salt), ikm)
919        .expand(info, &mut *okm)
920        .map_err(|_| Error::EncryptionError)?;
921    Ok(okm)
922}
923
924/// Used to generate random amount of data and store it in a Vec with a specific capacity
925pub(crate) fn generate<const N: usize>() -> [u8; N] {
926    let mut buffer: [u8; N] = [0u8; N];
927    OsRng.fill_bytes(&mut buffer);
928    buffer
929}