mwc_libp2p_core/identity/
secp256k1.rs1use asn1_der::{FromDerObject, DerObject};
24use rand::RngCore;
25use sha2::{Digest as ShaDigestTrait, Sha256};
26use secp256k1::{Message, Signature};
27use super::error::{DecodingError, SigningError};
28use zeroize::Zeroize;
29use core::fmt;
30
31#[derive(Clone)]
33pub struct Keypair {
34 secret: SecretKey,
35 public: PublicKey
36}
37
38impl Keypair {
39 pub fn generate() -> Keypair {
41 Keypair::from(SecretKey::generate())
42 }
43
44 pub fn public(&self) -> &PublicKey {
46 &self.public
47 }
48
49 pub fn secret(&self) -> &SecretKey {
51 &self.secret
52 }
53}
54
55impl fmt::Debug for Keypair {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 f.debug_struct("Keypair").field("public", &self.public).finish()
58 }
59}
60
61impl From<SecretKey> for Keypair {
63 fn from(secret: SecretKey) -> Keypair {
64 let public = PublicKey(secp256k1::PublicKey::from_secret_key(&secret.0));
65 Keypair { secret, public }
66 }
67}
68
69impl From<Keypair> for SecretKey {
71 fn from(kp: Keypair) -> SecretKey {
72 kp.secret
73 }
74}
75
76#[derive(Clone)]
78pub struct SecretKey(secp256k1::SecretKey);
79
80impl fmt::Debug for SecretKey {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 write!(f, "SecretKey")
83 }
84}
85
86impl SecretKey {
87 pub fn generate() -> SecretKey {
89 let mut r = rand::thread_rng();
90 let mut b = [0; secp256k1::util::SECRET_KEY_SIZE];
91 loop {
94 r.fill_bytes(&mut b);
95 if let Ok(k) = secp256k1::SecretKey::parse(&b) {
96 return SecretKey(k)
97 }
98 }
99 }
100
101 pub fn from_bytes(mut sk: impl AsMut<[u8]>) -> Result<SecretKey, DecodingError> {
105 let sk_bytes = sk.as_mut();
106 let secret = secp256k1::SecretKey::parse_slice(&*sk_bytes)
107 .map_err(|_| DecodingError::new("failed to parse secp256k1 secret key"))?;
108 sk_bytes.zeroize();
109 Ok(SecretKey(secret))
110 }
111
112 pub fn from_der(mut der: impl AsMut<[u8]>) -> Result<SecretKey, DecodingError> {
117 let der_obj = der.as_mut();
119 let obj: Vec<DerObject> = FromDerObject::deserialize((&*der_obj).iter())
120 .map_err(|e| DecodingError::new("Secp256k1 DER ECPrivateKey").source(e))?;
121 der_obj.zeroize();
122 let sk_obj = obj.into_iter().nth(1)
123 .ok_or_else(|| DecodingError::new("Not enough elements in DER"))?;
124 let mut sk_bytes: Vec<u8> = FromDerObject::from_der_object(sk_obj)
125 .map_err(DecodingError::new)?;
126 let sk = SecretKey::from_bytes(&mut sk_bytes)?;
127 sk_bytes.zeroize();
128 Ok(sk)
129 }
130
131 pub fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
136 self.sign_hash(Sha256::digest(msg).as_ref())
137 }
138
139 pub fn to_bytes(&self) -> [u8; 32] {
141 self.0.serialize()
142 }
143
144 pub fn sign_hash(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
147 let m = Message::parse_slice(msg)
148 .map_err(|_| SigningError::new("failed to parse secp256k1 digest"))?;
149 Ok(secp256k1::sign(&m, &self.0).0.serialize_der().as_ref().into())
150 }
151}
152
153#[derive(PartialEq, Eq, Clone, Debug)]
155pub struct PublicKey(secp256k1::PublicKey);
156
157impl PublicKey {
158 pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
160 self.verify_hash(Sha256::digest(msg).as_ref(), sig)
161 }
162
163 pub fn verify_hash(&self, msg: &[u8], sig: &[u8]) -> bool {
165 Message::parse_slice(msg)
166 .and_then(|m| Signature::parse_der(sig).map(|s| secp256k1::verify(&m, &s, &self.0)))
167 .unwrap_or(false)
168 }
169
170 pub fn encode(&self) -> [u8; 33] {
173 self.0.serialize_compressed()
174 }
175
176 pub fn encode_uncompressed(&self) -> [u8; 65] {
178 self.0.serialize()
179 }
180
181 pub fn decode(k: &[u8]) -> Result<PublicKey, DecodingError> {
184 secp256k1::PublicKey::parse_slice(k, Some(secp256k1::PublicKeyFormat::Compressed))
185 .map_err(|_| DecodingError::new("failed to parse secp256k1 public key"))
186 .map(PublicKey)
187 }
188}
189
190#[cfg(test)]
191mod tests {
192 use super::*;
193
194 #[test]
195 fn secp256k1_secret_from_bytes() {
196 let sk1 = SecretKey::generate();
197 let mut sk_bytes = [0; 32];
198 sk_bytes.copy_from_slice(&sk1.0.serialize()[..]);
199 let sk2 = SecretKey::from_bytes(&mut sk_bytes).unwrap();
200 assert_eq!(sk1.0.serialize(), sk2.0.serialize());
201 assert_eq!(sk_bytes, [0; 32]);
202 }
203}