ecies_ed25519/
keys.rs

1use super::Error;
2use core::iter::FromIterator;
3use curve25519_dalek::constants;
4use curve25519_dalek::edwards::{CompressedEdwardsY, EdwardsPoint};
5use curve25519_dalek::scalar::Scalar;
6use hex::{FromHex, ToHex};
7use rand::{CryptoRng, RngCore};
8use zeroize::Zeroize;
9
10/// The length of a `SecretKey`, in bytes.
11pub const SECRET_KEY_LENGTH: usize = 32;
12
13/// The length of a `PublicKey`, in bytes.
14pub const PUBLIC_KEY_LENGTH: usize = 32;
15
16/// Secret Key
17///
18/// Neither this secret key (nor it's corresponding PublicKey) should be used for signing
19/// or in any other protocol other than ECIES.
20#[derive(Debug)]
21pub struct SecretKey(pub(crate) [u8; SECRET_KEY_LENGTH]);
22
23/// Zero a secretKey when it's dropped
24impl Drop for SecretKey {
25    fn drop(&mut self) {
26        self.0.zeroize();
27    }
28}
29
30impl ToHex for SecretKey {
31    fn encode_hex<T: FromIterator<char>>(&self) -> T {
32        self.0.encode_hex()
33    }
34
35    fn encode_hex_upper<T: FromIterator<char>>(&self) -> T {
36        self.0.encode_hex_upper()
37    }
38}
39
40impl FromHex for SecretKey {
41    type Error = Error;
42
43    fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Error> {
44        let mut bytes = Vec::<u8>::from_hex(hex).map_err(|_| Error::InvalidSecretKeyBytes)?;
45        let sk = Self::from_bytes(&bytes)?;
46        bytes.zeroize();
47        Ok(sk)
48    }
49}
50
51impl SecretKey {
52    /// Convert this secret key to a byte array.
53    #[inline]
54    pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
55        self.0
56    }
57
58    /// View this secret key as a byte array.
59    #[inline]
60    pub fn as_bytes(&self) -> &[u8; SECRET_KEY_LENGTH] {
61        &self.0
62    }
63
64    /// Construct a `SecretKey` from a slice of bytes.
65    ///
66    /// # Example
67    ///
68    /// ```
69    /// use ecies_ed25519::SecretKey;
70    /// use ecies_ed25519::SECRET_KEY_LENGTH;
71    /// use ecies_ed25519::Error;
72    ///
73    /// # fn doctest() -> Result<SecretKey, Error> {
74    /// let secret_key_bytes: [u8; SECRET_KEY_LENGTH] = [
75    ///    157, 097, 177, 157, 239, 253, 090, 096,
76    ///    186, 132, 074, 244, 146, 236, 044, 196,
77    ///    068, 073, 197, 105, 123, 050, 105, 025,
78    ///    112, 059, 172, 003, 028, 174, 127, 096, ];
79    ///
80    /// let secret_key: SecretKey = SecretKey::from_bytes(&secret_key_bytes)?;
81    /// #
82    /// # Ok(secret_key)
83    /// # }
84    /// #
85    /// # fn main() {
86    /// #     let result = doctest();
87    /// #     assert!(result.is_ok());
88    /// # }
89    /// ```
90    #[inline]
91    pub fn from_bytes(bytes: &[u8]) -> Result<SecretKey, Error> {
92        if bytes.len() != SECRET_KEY_LENGTH {
93            return Err(Error::InvalidSecretKeyBytes);
94        }
95        let mut bits: [u8; 32] = [0u8; 32];
96        bits.copy_from_slice(&bytes[..32]);
97
98        Ok(SecretKey(bits))
99    }
100
101    /// Generate a `SecretKey` from a `csprng`.
102    pub fn generate<T>(csprng: &mut T) -> SecretKey
103    where
104        T: CryptoRng + RngCore,
105    {
106        let mut sk: SecretKey = SecretKey([0u8; 32]);
107        csprng.fill_bytes(&mut sk.0);
108        sk
109    }
110}
111
112/// Public Key
113///
114/// Neither this public key (nor it's corresponding  PrivateKey) should be used for signing
115/// or in any other protocol other than ECIES.
116#[derive(Copy, Clone, Default, Eq, PartialEq, Debug)]
117pub struct PublicKey(pub(crate) CompressedEdwardsY);
118
119impl PublicKey {
120    /// Convert this public key to a byte array.
121    #[inline]
122    pub fn to_bytes(&self) -> [u8; PUBLIC_KEY_LENGTH] {
123        self.0.to_bytes()
124    }
125
126    /// View this public key as a byte array.
127    #[inline]
128    pub fn as_bytes(&self) -> &[u8; PUBLIC_KEY_LENGTH] {
129        self.0.as_bytes()
130    }
131
132    /// Construct a `PublicKey` from a slice of bytes.
133    ///
134    /// Will return None if the bytes are invalid
135    #[inline]
136    pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
137        if bytes.len() != PUBLIC_KEY_LENGTH {
138            return Err(Error::InvalidPublicKeyBytes);
139        }
140
141        let point = CompressedEdwardsY::from_slice(bytes);
142
143        if point.decompress().is_none() {
144            return Err(Error::InvalidPublicKeyBytes);
145        }
146        Ok(PublicKey(point))
147    }
148
149    /// Derive a public key from a private key
150    pub fn from_secret(sk: &SecretKey) -> Self {
151        let point = &Scalar::from_bits(sk.to_bytes()) * &constants::ED25519_BASEPOINT_TABLE;
152        PublicKey(point.compress())
153    }
154
155    /// Get the Edwards Point for this public key
156    pub fn to_point(&self) -> EdwardsPoint {
157        CompressedEdwardsY::from_slice(self.0.as_bytes())
158            .decompress()
159            .expect("ecies-ed25519: unexpect error decompressing public key")
160    }
161}
162
163// Note: ToHex is implemented implicitly through impl AsRef<[u8]> for PublicKey
164impl FromHex for PublicKey {
165    type Error = Error;
166
167    fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Error> {
168        let mut bytes = Vec::<u8>::from_hex(hex).map_err(|_| Error::InvalidPublicKeyBytes)?;
169        let sk = Self::from_bytes(&bytes)?;
170        bytes.zeroize();
171        Ok(sk)
172    }
173}
174
175impl AsRef<[u8]> for PublicKey {
176    fn as_ref(&self) -> &[u8] {
177        self.as_bytes()
178    }
179}
180
181// "serde" feature
182// ---------------
183
184#[cfg(feature = "serde")]
185use serde::{
186    de::Error as SerdeError, de::Unexpected, de::Visitor, Deserialize, Deserializer, Serialize,
187    Serializer,
188};
189
190#[cfg(feature = "serde")]
191impl Serialize for SecretKey {
192    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
193    where
194        S: Serializer,
195    {
196        if serializer.is_human_readable() {
197            let encoded: Vec<char> = self.encode_hex();
198            let mut encoded: String = encoded.into_iter().collect();
199            let result = serializer.serialize_str(&encoded);
200
201            encoded.zeroize();
202
203            result
204        } else {
205            serializer.serialize_bytes(self.as_bytes())
206        }
207    }
208}
209
210#[cfg(feature = "serde")]
211impl<'d> Deserialize<'d> for SecretKey {
212    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
213    where
214        D: Deserializer<'d>,
215    {
216        struct SecretKeyVisitor;
217
218        impl<'d> Visitor<'d> for SecretKeyVisitor {
219            type Value = SecretKey;
220
221            fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
222                formatter.write_str("An ecies-ed25519 secret key as 32 bytes.")
223            }
224
225            fn visit_str<E>(self, input: &str) -> Result<SecretKey, E>
226            where
227                E: SerdeError,
228            {
229                let mut bytes = hex::decode(input).or(Err(SerdeError::invalid_value(
230                    Unexpected::Other("invalid hex"),
231                    &self,
232                )))?;
233                let sk = SecretKey::from_bytes(&bytes)
234                    .or(Err(SerdeError::invalid_length(bytes.len(), &self)))?;
235                bytes.zeroize();
236                Ok(sk)
237            }
238
239            fn visit_bytes<E>(self, bytes: &[u8]) -> Result<SecretKey, E>
240            where
241                E: SerdeError,
242            {
243                SecretKey::from_bytes(bytes).or(Err(SerdeError::invalid_length(bytes.len(), &self)))
244            }
245        }
246        if deserializer.is_human_readable() {
247            deserializer.deserialize_str(SecretKeyVisitor)
248        } else {
249            deserializer.deserialize_bytes(SecretKeyVisitor)
250        }
251    }
252}
253
254#[cfg(feature = "serde")]
255impl Serialize for PublicKey {
256    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
257    where
258        S: Serializer,
259    {
260        if serializer.is_human_readable() {
261            let encoded: Vec<char> = self.encode_hex();
262            let mut encoded: String = encoded.into_iter().collect();
263            let result = serializer.serialize_str(&encoded);
264
265            encoded.zeroize();
266
267            result
268        } else {
269            serializer.serialize_bytes(self.as_bytes())
270        }
271    }
272}
273
274#[cfg(feature = "serde")]
275impl<'d> Deserialize<'d> for PublicKey {
276    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
277    where
278        D: Deserializer<'d>,
279    {
280        struct PublicKeyVisitor;
281
282        impl<'d> Visitor<'d> for PublicKeyVisitor {
283            type Value = PublicKey;
284
285            fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
286                formatter.write_str("An ecies-ed25519 public key as 32 bytes.")
287            }
288
289            fn visit_str<E>(self, input: &str) -> Result<PublicKey, E>
290            where
291                E: SerdeError,
292            {
293                if input.len() != PUBLIC_KEY_LENGTH * 2 {
294                    return Err(SerdeError::invalid_length(input.len(), &self));
295                }
296                let mut bytes = hex::decode(input).or(Err(SerdeError::invalid_value(
297                    Unexpected::Other("invalid hex"),
298                    &self,
299                )))?;
300                let pk = PublicKey::from_bytes(&bytes).map_err(|e| SerdeError::custom(e))?;
301                bytes.zeroize();
302                Ok(pk)
303            }
304
305            fn visit_bytes<E>(self, bytes: &[u8]) -> Result<PublicKey, E>
306            where
307                E: SerdeError,
308            {
309                if bytes.len() != PUBLIC_KEY_LENGTH {
310                    return Err(SerdeError::invalid_length(bytes.len(), &self));
311                }
312                PublicKey::from_bytes(bytes).map_err(|e| SerdeError::custom(e))
313            }
314        }
315
316        if deserializer.is_human_readable() {
317            deserializer.deserialize_str(PublicKeyVisitor)
318        } else {
319            deserializer.deserialize_bytes(PublicKeyVisitor)
320        }
321    }
322}