core_crypto/
keypair.rs

1// Copyright 2021 BlockPuppets developers.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! A Rust implementation of Nis1 and Symbol ed25519 keypair generation, signing, and verification.
10//!
11//! This is the reference documentation for the proptest API.
12//!
13//! For documentation on how to get started with Nis1 keypair and general usage
14//! advice, please refer to the [Key pair](https://docs.nem.io/en/nem-sdk/private-key#6-2-create-key-pairs).
15//!
16//! For documentation on how to get started with Symbol keypair and general usage
17//! advice, please refer to the [Key pair](https://docs.symbolplatform.com/concepts/cryptography.html#keypair).
18//!
19
20use std::fmt;
21use std::fmt::Debug;
22
23use anyhow::Result;
24#[cfg(feature = "serde")]
25use serde::{Deserialize, Deserializer, Serialize, Serializer};
26#[cfg(feature = "serde")]
27use serde::de::Error as SerdeError;
28#[cfg(feature = "serde")]
29use serde_bytes::{ByteBuf as SerdeByteBuf, Bytes as SerdeBytes};
30use crate::{KeyPairSchema, PrivateKey, KEYPAIR_LENGTH, KEY_BYTES_SIZE, Signature, PublicKey, BlockCipher};
31
32/// It represents an asymmetric private/public encryption key.
33///
34#[derive(Debug, Clone, Copy, PartialEq, Hash)]
35pub struct Keypair<Kp: KeyPairSchema>(pub Kp);
36
37impl<Kp: KeyPairSchema> Keypair<Kp> {
38    /// Generate a `Keypair` random.
39    ///
40    /// # Example
41    ///
42    /// ```
43    /// use symbol_crypto_core::prelude::{Keypair, Sym};
44    /// #
45    /// # fn main() {
46    /// #
47    /// let keypair = Keypair::<Sym>::random();
48    /// # println!("{}", keypair);
49    /// # }
50    /// ```
51    pub fn random() -> Self {
52        Self(<Kp>::random())
53    }
54
55    /// Construct a `Keypair` from the bytes of a `PublicKey` and `PrivateKey`.
56    ///
57    /// # Inputs
58    ///
59    /// * `bytes`: an `&[u8]` representing the `PublicKey` and `PrivateKey` as bytes.
60    ///
61    /// # Returns
62    ///
63    /// A `Result` whose okay value is a `Keypair` or whose error value
64    /// is an describing the error that occurred.
65    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
66        let kp = <Kp>::from_bytes(bytes)?;
67        Ok(Self(kp))
68    }
69
70    /// Construct a `Keypair` from a hex encoded private key string.
71    ///
72    /// # Inputs
73    ///
74    /// * `hex`: an `S` representing the hex private key (String or &str).
75    ///
76    /// # Example
77    ///
78    /// ```
79    /// use symbol_crypto_core::prelude::{Keypair, Sym};
80    /// #
81    /// # fn main() {
82    /// #
83    /// let private_key_hex: &str =
84    /// "7D3E959EB0CD66CC1DB6E9C62CB81EC52747AB56FA740CF18AACB5003429AD2E";
85    /// let keypair = Keypair::<Sym>::from_hex_private_key(private_key_hex);
86    /// # assert!(keypair.is_ok());
87    /// # }
88    /// ```
89    ///
90    /// # Returns
91    ///
92    /// A `Result` whose okay value is an `Keypair` or whose error value
93    /// is an `failure::Error` describing the error that occurred.
94    pub fn from_hex_private_key<S: AsRef<str>>(hex: S) -> Result<Self> {
95        let kp = <Kp>::from_hex_private_key(hex)?;
96        Ok(Self(kp))
97    }
98
99    /// Construct a `Keypair` `PrivateKey` type.
100    ///
101    /// # Inputs
102    ///
103    /// * `private_key`: representing the `PrivateKey` type.
104    ///
105    /// # Example
106    ///
107    /// ```
108    /// # use std::str::FromStr;
109    /// use symbol_crypto_core::prelude::{Keypair, PrivateKey, Sym};
110    /// #
111    /// # fn main() {
112    /// #
113    /// let private_key_hex: &str = "7D3E959EB0CD66CC1DB6E9C62CB81EC52747AB56FA740CF18AACB5003429AD2E";
114    /// let private_key = PrivateKey::from_str(private_key_hex).unwrap();
115    /// let keypair = Keypair::<Sym>::from_private_key(private_key);
116    /// # }
117    /// ```
118    ///
119    /// # Returns
120    ///
121    /// A `Keypair`
122    pub fn from_private_key(private_key: PrivateKey) -> Self {
123        let kp = <Kp>::from_private_key(private_key);
124        Self(kp)
125    }
126
127    /// Convert this keypair to bytes.
128    ///
129    /// # Returns
130    ///
131    /// An array of bytes, `[u8; KEYPAIR_LENGTH]`.  The first
132    /// `KEY_BYTES_SIZE` of bytes is the `PrivateKey`, and the next
133    /// `KEY_BYTES_SIZE` bytes is the `PublicKey`.
134    pub fn to_bytes(&self) -> [u8; KEYPAIR_LENGTH] {
135        let mut bytes: [u8; KEYPAIR_LENGTH] = [0u8; KEYPAIR_LENGTH];
136
137        bytes[..KEY_BYTES_SIZE].copy_from_slice(self.0.private_key().as_bytes());
138        bytes[KEY_BYTES_SIZE..].copy_from_slice(self.0.public_key().as_bytes());
139        bytes
140    }
141
142    /// Signs a data bytes with a `Keypair`.
143    ///
144    /// # Inputs
145    ///
146    /// * `data`: an `&[u8]` representing the data to sign.
147    ///
148    /// # Example
149    ///
150    /// ```
151    /// use symbol_crypto_core::prelude::{Keypair, Sym};
152    /// #
153    /// # fn main() {
154    /// #
155    /// let keypair = Keypair::<Sym>::random();
156    /// let data = b"8ce03cd60514233b86789729102ea09e867fc6d964dea8c2018ef7d0a2e0e24bf7e348e917116690b9";
157    ///
158    /// let signature = keypair.sign(data.as_ref());
159    /// # }
160    /// ```
161    ///
162    /// # Returns
163    ///
164    /// A `Signature` the signature hash.
165    pub fn sign(&self, data: &[u8]) -> Signature {
166        self.0.sign(data)
167    }
168
169    /// Verify a `Signature` on a data with this Keypair public key.
170    ///
171    /// # Inputs
172    ///
173    /// * `data`: an `&[u8]` the data to verify.
174    ///
175    /// * `signature`: an `Signature` the signature hash.
176    ///
177    /// # Returns
178    ///
179    /// Returns `Ok` if the `Signature` was a valid signature created by this `Keypair`
180    ///
181    pub fn verify(&self, data: &[u8], signature: Signature) -> Result<()> {
182        self.0.verify(data, signature)
183    }
184
185    pub fn private_key(&self) -> PrivateKey {
186        self.0.private_key()
187    }
188
189    pub fn public_key(&self) -> PublicKey {
190        self.0.public_key()
191    }
192
193    /// Encode a message text using the signer's `PrivateKey` of this Keypair and receiver's
194    /// `PublicKey`.
195    ///
196    /// # Inputs
197    ///
198    /// * `receiver_pk`: The receiver's public key.
199    ///
200    /// * `msg`: Message to encrypt.
201    ///
202    /// # Example
203    ///
204    /// ```
205    /// # use std::str::FromStr;
206    /// use symbol_crypto_core::prelude::{Keypair, Sym, PublicKey};
207    ///
208    /// # fn main() {
209    /// #
210    /// # let signer_kp = Keypair::<Sym>::random();
211    /// # let receiver_pk = PublicKey::from_str("645C6BB6526E209ED33162472BF75F06172309DC72214AE07CE68EB5A6496B4E").unwrap();
212    ///
213    /// let message = b"Symbol is awesome from Rust!";
214    ///
215    /// let encrypt_text = signer_kp.encrypt_message(receiver_pk.as_fixed_bytes(), message).unwrap();
216    /// # println!("{:?}", encrypt_text);
217    /// # }
218    /// ```
219    ///
220    /// # Returns
221    ///
222    /// A `Result` whose okay value is an encrypt message `Vec<u8>` or whose error value
223    /// is an `failure::Error` describing the error that occurred.
224    pub fn encrypt_message(
225        &self,
226        receiver_pk: &[u8; KEY_BYTES_SIZE],
227        msg: &[u8],
228    ) -> Result<Vec<u8>> {
229        <Kp>::Crypto::encrypt_message(self.private_key().as_fixed_bytes(), receiver_pk, msg)
230    }
231
232    /// Decrypt a message text using the receiver's the PrivateKey of this Keypair and signer's
233    /// PublicKey.
234    ///
235    /// # Inputs
236    ///
237    /// * `signer_pk`: The signer's public key.
238    ///
239    /// * `enc_msg`: Message encrypted.
240    ///
241    /// # Example
242    ///
243    /// ```
244    /// # use std::str::FromStr;
245    /// use symbol_crypto_core::prelude::{Keypair, Sym, PublicKey};
246    ///
247    /// # fn main() {
248    /// #
249    /// let receiver_kp = Keypair::<Sym>::from_hex_private_key("A22A4BBF126A2D7D7ECE823174DFD184C5DE0FDE4CB2075D30CFA409F7EF8908").unwrap();
250    /// let signer_pk = PublicKey::from_str("3FD283D8543C12B81917C154CDF4EFD3D48E553E6D7BC77E29CB168138CED17D").unwrap();
251    ///
252    /// let encrypt_text_vec = [
253    ///     125, 59, 126, 248, 124, 129, 157, 100, 111, 84, 49, 163, 111, 68, 22, 137, 75, 132, 135,
254    ///     217, 251, 158, 115, 74, 226, 172, 200, 208, 33, 183, 110, 103, 107, 170, 52, 174, 192, 110,
255    ///     164, 44, 77, 69, 203, 48, 43, 17, 206, 143, 154, 155, 231, 72, 28, 24, 20, 241, 234, 202,
256    ///     184, 66,
257    /// ];
258    ///
259    /// let decrypted_text = receiver_kp.decrypt_message( signer_pk.as_fixed_bytes(), &encrypt_text_vec).unwrap();
260    /// # println!("{}", String::from_utf8(decrypted_text).unwrap());
261    /// # }
262    /// ```
263    ///
264    /// # Returns
265    ///
266    /// A `Result` whose okay value is an decrypted message `Vec<u8>` or whose error value
267    /// is an `failure::Error` describing the error that occurred.
268    pub fn decrypt_message(
269        &self,
270        signer_pk: &[u8; KEY_BYTES_SIZE],
271        enc_msg: &[u8],
272    ) -> Result<Vec<u8>> {
273        <Kp>::Crypto::decrypt_message(self.private_key().as_fixed_bytes(), signer_pk, enc_msg)
274    }
275}
276
277impl<C: KeyPairSchema> fmt::Display for Keypair<C> {
278    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
279        write!(f, "{{public_key: {:x}}}", self.public_key())
280    }
281}
282
283#[cfg(feature = "serde")]
284impl<C: KeyPairSchema> Serialize for Keypair<C> {
285    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
286        where
287            S: Serializer,
288    {
289        let bytes = &self.to_bytes()[..];
290        SerdeBytes::new(bytes).serialize(serializer)
291    }
292}
293
294#[cfg(feature = "serde")]
295impl<'d, C: KeyPairSchema> Deserialize<'d> for Keypair<C> {
296    fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
297        where
298            D: Deserializer<'d>,
299    {
300        let bytes = <SerdeByteBuf>::deserialize(deserializer)?;
301        Keypair::from_bytes(bytes.as_ref()).map_err(SerdeError::custom)
302    }
303}
304
305impl<C: KeyPairSchema> AsRef<C> for Keypair<C> {
306    fn as_ref(&self) -> &C {
307        &self.0
308    }
309}