libp2p_identity/
secp256k1.rs1use super::error::DecodingError;
24use asn1_der::typed::{DerDecodable, Sequence};
25use core::cmp;
26use core::fmt;
27use core::hash;
28use libsecp256k1::{Message, Signature};
29use sha2::{Digest as ShaDigestTrait, Sha256};
30use zeroize::Zeroize;
31
32#[derive(Clone)]
34pub struct Keypair {
35 secret: SecretKey,
36 public: PublicKey,
37}
38
39impl Keypair {
40 #[cfg(feature = "rand")]
42 pub fn generate() -> Keypair {
43 Keypair::from(SecretKey::generate())
44 }
45
46 pub fn public(&self) -> &PublicKey {
48 &self.public
49 }
50
51 pub fn secret(&self) -> &SecretKey {
53 &self.secret
54 }
55}
56
57impl fmt::Debug for Keypair {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 f.debug_struct("Keypair")
60 .field("public", &self.public)
61 .finish()
62 }
63}
64
65impl From<SecretKey> for Keypair {
67 fn from(secret: SecretKey) -> Keypair {
68 let public = PublicKey(libsecp256k1::PublicKey::from_secret_key(&secret.0));
69 Keypair { secret, public }
70 }
71}
72
73impl From<Keypair> for SecretKey {
75 fn from(kp: Keypair) -> SecretKey {
76 kp.secret
77 }
78}
79
80#[derive(Clone)]
82pub struct SecretKey(libsecp256k1::SecretKey);
83
84impl fmt::Debug for SecretKey {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 write!(f, "SecretKey")
87 }
88}
89
90impl SecretKey {
91 #[cfg(feature = "rand")]
93 pub fn generate() -> SecretKey {
94 SecretKey(libsecp256k1::SecretKey::random(&mut rand::thread_rng()))
95 }
96
97 pub fn try_from_bytes(mut sk: impl AsMut<[u8]>) -> Result<SecretKey, DecodingError> {
103 let sk_bytes = sk.as_mut();
104 let secret = libsecp256k1::SecretKey::parse_slice(&*sk_bytes)
105 .map_err(|e| DecodingError::failed_to_parse("parse secp256k1 secret key", e))?;
106 sk_bytes.zeroize();
107 Ok(SecretKey(secret))
108 }
109
110 pub fn from_der(mut der: impl AsMut<[u8]>) -> Result<SecretKey, DecodingError> {
115 let der_obj = der.as_mut();
117
118 let mut sk_bytes = Sequence::decode(der_obj)
119 .and_then(|seq| seq.get(1))
120 .and_then(Vec::load)
121 .map_err(|e| DecodingError::failed_to_parse("secp256k1 SecretKey bytes", e))?;
122
123 let sk = SecretKey::try_from_bytes(&mut sk_bytes)?;
124 sk_bytes.zeroize();
125 der_obj.zeroize();
126 Ok(sk)
127 }
128
129 pub fn sign(&self, msg: &[u8]) -> Vec<u8> {
134 let generic_array = Sha256::digest(msg);
135
136 let mut array = [0u8; 32];
138 array.copy_from_slice(generic_array.as_slice());
139
140 let message = Message::parse(&array);
141
142 libsecp256k1::sign(&message, &self.0)
143 .0
144 .serialize_der()
145 .as_ref()
146 .into()
147 }
148
149 pub fn to_bytes(&self) -> [u8; 32] {
151 self.0.serialize()
152 }
153}
154
155#[derive(Eq, Clone)]
157pub struct PublicKey(libsecp256k1::PublicKey);
158
159impl fmt::Debug for PublicKey {
160 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161 f.write_str("PublicKey(compressed): ")?;
162 for byte in &self.to_bytes() {
163 write!(f, "{byte:x}")?;
164 }
165 Ok(())
166 }
167}
168
169impl cmp::PartialEq for PublicKey {
170 fn eq(&self, other: &Self) -> bool {
171 self.to_bytes().eq(&other.to_bytes())
172 }
173}
174
175impl hash::Hash for PublicKey {
176 fn hash<H: hash::Hasher>(&self, state: &mut H) {
177 self.to_bytes().hash(state);
178 }
179}
180
181impl cmp::PartialOrd for PublicKey {
182 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
183 Some(self.cmp(other))
184 }
185}
186
187impl cmp::Ord for PublicKey {
188 fn cmp(&self, other: &Self) -> cmp::Ordering {
189 self.to_bytes().cmp(&other.to_bytes())
190 }
191}
192
193impl PublicKey {
194 pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
196 self.verify_hash(Sha256::digest(msg).as_ref(), sig)
197 }
198
199 pub fn verify_hash(&self, msg: &[u8], sig: &[u8]) -> bool {
201 Message::parse_slice(msg)
202 .and_then(|m| Signature::parse_der(sig).map(|s| libsecp256k1::verify(&m, &s, &self.0)))
203 .unwrap_or(false)
204 }
205
206 pub fn to_bytes(&self) -> [u8; 33] {
209 self.0.serialize_compressed()
210 }
211
212 pub fn to_bytes_uncompressed(&self) -> [u8; 65] {
214 self.0.serialize()
215 }
216
217 pub fn try_from_bytes(k: &[u8]) -> Result<PublicKey, DecodingError> {
220 libsecp256k1::PublicKey::parse_slice(k, Some(libsecp256k1::PublicKeyFormat::Compressed))
221 .map_err(|e| DecodingError::failed_to_parse("secp256k1 public key", e))
222 .map(PublicKey)
223 }
224}
225
226#[cfg(test)]
227mod tests {
228 use super::*;
229
230 #[test]
231 #[cfg(feature = "rand")]
232 fn secp256k1_secret_from_bytes() {
233 let sk1 = SecretKey::generate();
234 let mut sk_bytes = [0; 32];
235 sk_bytes.copy_from_slice(&sk1.0.serialize()[..]);
236 let sk2 = SecretKey::try_from_bytes(&mut sk_bytes).unwrap();
237 assert_eq!(sk1.0.serialize(), sk2.0.serialize());
238 assert_eq!(sk_bytes, [0; 32]);
239 }
240}