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}