owl_crypto/crypto/
keys.rs

1// This file is part of the owl-crypto.
2//
3// Copyright (C) 2022 Ade M Ramdani
4//
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
7// This program is free software: you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
20use rand::RngCore;
21
22pub enum KeyError {
23    InvalidKey,
24    InvalidLength(usize, usize),
25    InvalidHex,
26}
27
28impl std::fmt::Display for KeyError {
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        match self {
31            KeyError::InvalidKey => write!(f, "Invalid key"),
32            KeyError::InvalidLength(actual, expected) => write!(
33                f,
34                "Invalid key length. Expected {} but got {}",
35                expected, actual
36            ),
37            KeyError::InvalidHex => write!(f, "Invalid hex"),
38        }
39    }
40}
41
42impl std::fmt::Debug for KeyError {
43    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        std::fmt::Display::fmt(self, f)
45    }
46}
47
48/// Wrapper around secp256k1 secret key represented as 32-byte array.
49#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
50pub struct SecretKey([u8; 32]);
51
52/// Wrapper around secp256k1 public key represented as 65-byte array.
53#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
54pub struct PublicKey([u8; 65]);
55
56impl SecretKey {
57    /// Creates new random secret key.
58    pub fn new() -> Self {
59        let mut bytes = [0u8; 32];
60        rand::thread_rng().fill_bytes(&mut bytes);
61        SecretKey(bytes)
62    }
63
64    /// Creates new secret key from 32-byte array.
65    pub fn from_bytes(bytes: [u8; 32]) -> Self {
66        SecretKey(bytes)
67    }
68
69    /// Creates new secret key from slice of bytes.
70    /// Panics if slice is not 32 bytes long.
71    pub fn from_slice(bytes: &[u8]) -> Result<Self, KeyError> {
72        if bytes.len() != 32 {
73            return Err(KeyError::InvalidLength(bytes.len(), 32));
74        }
75        let mut array = [0u8; 32];
76        array.copy_from_slice(bytes);
77        Ok(SecretKey(array))
78    }
79
80    /// Creates new secret key from hex string.
81    /// Panics if string is not 32 bytes long.
82    pub fn from_hex(hex: &str) -> Result<Self, KeyError> {
83        let x = hex.trim_start_matches("0x");
84
85        if x.len() != 64 {
86            return Err(KeyError::InvalidLength(x.len(), 64));
87        }
88
89        let bytes = hex::decode(x).map_err(|_| KeyError::InvalidHex)?;
90        SecretKey::from_slice(&bytes)
91    }
92
93    /// Returns secret key as 32-byte array.
94    pub fn to_bytes(&self) -> [u8; 32] {
95        self.0
96    }
97
98    /// Returns secret key as slice of bytes.
99    pub fn to_slice(&self) -> &[u8] {
100        &self.0
101    }
102
103    /// Returns secret key as hex string.
104    pub fn to_hex(&self) -> String {
105        hex::encode(&self.0)
106    }
107
108    /// Returns public key corresponding to this secret key.
109    pub fn public_key(&self) -> Result<PublicKey, KeyError> {
110        let secp = secp256k1::Secp256k1::new();
111        let sk = secp256k1::SecretKey::from_slice(&self.0).map_err(|_| KeyError::InvalidKey)?;
112        let pk = secp256k1::PublicKey::from_secret_key(&secp, &sk);
113
114        let mut bytes = [0u8; 65];
115        bytes.copy_from_slice(&pk.serialize_uncompressed());
116        Ok(PublicKey(bytes))
117    }
118}
119
120impl std::fmt::Display for SecretKey {
121    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
122        write!(f, "{}", self.to_hex())
123    }
124}
125
126impl std::fmt::Debug for SecretKey {
127    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128        write!(f, "{}", self.to_hex())
129    }
130}
131
132impl PublicKey {
133    /// Creates new public key from 65-byte array.
134    pub fn from_bytes(bytes: [u8; 65]) -> Self {
135        PublicKey(bytes)
136    }
137
138    /// Creates new public key from slice of bytes.
139    /// Panics if slice is not 65 bytes long.
140    pub fn from_slice(bytes: &[u8]) -> Result<Self, KeyError> {
141        if bytes.len() != 65 {
142            return Err(KeyError::InvalidLength(bytes.len(), 65));
143        }
144        let mut array = [0u8; 65];
145        array.copy_from_slice(bytes);
146        Ok(PublicKey(array))
147    }
148
149    /// Creates new public key from hex string.
150    /// Panics if string is not 65 bytes long.
151    pub fn from_hex(hex: &str) -> Result<Self, KeyError> {
152        let x = hex.trim_start_matches("0x");
153
154        if x.len() != 130 {
155            return Err(KeyError::InvalidLength(x.len(), 130));
156        }
157
158        let bytes = hex::decode(x).map_err(|_| KeyError::InvalidHex)?;
159        PublicKey::from_slice(&bytes)
160    }
161
162    /// Create new public key from secret key.
163    pub fn from_secret_key(secret_key: &SecretKey) -> Result<Self, KeyError> {
164        secret_key.public_key()
165    }
166
167    /// Returns public key as 65-byte array.
168    pub fn to_bytes(&self) -> [u8; 65] {
169        self.0
170    }
171
172    /// Returns public key as slice of bytes.
173    pub fn to_slice(&self) -> &[u8] {
174        &self.0
175    }
176
177    /// Returns public key as hex string.
178    pub fn to_hex(&self) -> String {
179        hex::encode(&self.0)
180    }
181}
182
183impl std::fmt::Display for PublicKey {
184    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
185        write!(f, "{}", self.to_hex())
186    }
187}
188
189impl std::fmt::Debug for PublicKey {
190    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
191        write!(f, "{}", self.to_hex())
192    }
193}
194
195/// Creates new random key pair.
196pub fn new_key_pair() -> Result<(SecretKey, PublicKey), KeyError> {
197    let secret_key = SecretKey::new();
198    let public_key = secret_key.public_key()?;
199    Ok((secret_key, public_key))
200}