simple_crypto/
secp256k1.rs

1use super::Error;
2
3use super::bip324::{PacketHandler, Handshake, Role};
4use super::structs::{Schemas, Hash};
5use super::traits::Hashable;
6
7use bitcoin_hashes::{Hash as BHash, hash160};
8use serde::{Serialize, Deserialize};
9use schemars::gen::SchemaGenerator;
10use secp256k1::schnorr::Signature;
11use secp256k1::{Message, Keypair};
12use secp256k1::ellswift::{ElligatorSwift, ElligatorSwiftParty};
13use bitcoin::NetworkKind;
14use bitcoin::bip32::{
15    ChildNumber,
16    Xpriv,
17};
18use schemars::schema::Schema;
19use schemars::JsonSchema;
20use either::Either;
21use bitcoin::Network;
22
23fn message(payload: &[u8]) -> Message {
24    Message::from_digest(payload.hash().to_arr())
25}
26
27#[derive(JsonSchema, Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
28pub struct Key {
29    inner: Either<PublicKey, SecretKey>
30}
31
32impl Key {
33    pub fn new_public(key: PublicKey) -> Self {Key{inner: Either::Left(key)}}
34    pub fn new_secret(key: SecretKey) -> Self {Key{inner: Either::Right(key)}}
35
36    pub fn public_key(&self) -> PublicKey {
37        self.inner.clone().left_or_else(|r| r.public_key())
38    }
39    pub fn secret_key(&self) -> Option<SecretKey> {self.inner.clone().right()}
40
41    pub fn secret_or(self, key: Key) -> Key {if self.inner.is_right() {self} else {key}}
42    pub fn to_public(self) -> Self {Self::new_public(self.public_key())}
43    pub fn is_public(&self) -> bool {self.inner.is_left()}
44}
45
46#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, PartialOrd, Ord)]
47pub struct PublicKey {
48    key: secp256k1::PublicKey
49}
50
51
52impl PublicKey {
53    pub fn to_vec(&self) -> Vec<u8> {
54        self.key.serialize().to_vec()
55    }
56    pub fn from_bytes(b: &[u8]) -> Result<Self, Error> {
57        Ok(PublicKey{key: secp256k1::PublicKey::from_slice(b)?})
58    }
59    pub fn thumbprint(&self) -> String {
60        hex::encode(hash160::Hash::hash(&self.key.serialize()))
61    }
62
63    pub fn verify(&self, payload: &[u8], signature: &[u8]) -> Result<(), Error> {
64        Ok(Signature::from_slice(signature)?.verify(
65            &message(payload),
66            &self.key.x_only_public_key().0
67        )?)
68    }
69
70    pub fn encrypt(&self, payload: &[u8]) -> Result<Vec<u8>, Error> {
71        let their_ell_swift = ElligatorSwift::from_pubkey(self.key);
72        let my_sec_key = SecretKey::new();
73        let my_ell_swift = ElligatorSwift::from_pubkey(my_sec_key.public_key().key);
74        let session_keys = Handshake::get_shared_secrets(
75            my_ell_swift,
76            their_ell_swift,
77            my_sec_key.key,
78            ElligatorSwiftParty::A,
79            Network::Bitcoin,
80        )?;
81        let mut packet_handler = PacketHandler::new(session_keys.clone(), Role::Initiator);
82        Ok([
83            my_ell_swift.to_array().to_vec(),
84            packet_handler.writer().encrypt_packet(payload, None)?
85        ].concat())
86    }
87}
88
89impl JsonSchema for PublicKey {
90    fn schema_name() -> String {"PublicKey".to_string()}
91    fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
92        Schemas::regex("^(0x|0X)?[a-fA-F0-9]{32}$".to_string())
93    }
94}
95
96impl std::fmt::Debug for PublicKey {
97    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98        write!(f, "{}", self)
99    }
100}
101
102impl std::fmt::Display for PublicKey {
103    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
104        write!(f, "{}", hex::encode(self.to_vec()))
105    }
106}
107
108#[derive(Clone, PartialEq, Eq)]
109#[derive(serde_with::SerializeDisplay)]
110#[derive(serde_with::DeserializeFromStr)]
111pub struct SecretKey {
112    key: secp256k1::SecretKey
113}
114
115impl SecretKey {
116    pub fn new() -> Self {
117        SecretKey{
118            key: secp256k1::SecretKey::new(&mut secp256k1::rand::thread_rng())
119        }
120    }
121    pub fn encrypt_self(&self, public_key: &PublicKey) -> Result<Vec<u8>, Error> {
122        public_key.encrypt(&serde_json::to_vec(&self.key)?)
123    }
124    pub fn sign(&self, payload: &[u8]) -> Vec<u8> {
125        Keypair::from_secret_key(
126            &secp256k1::Secp256k1::new(),
127            &self.key
128        ).sign_schnorr(message(payload)).serialize().to_vec()
129    }
130    pub fn decrypt(&self, payload: &[u8]) -> Result<Vec<u8>, Error> {
131        if payload.len() < 65 {return Err(Error::err("SecretKey.decrypt", "Payload was too small"));}
132        let their_ell_swift = ElligatorSwift::from_array(payload[0..64].try_into().unwrap());
133        let my_sec_key = self;
134        let my_ell_swift = ElligatorSwift::from_pubkey(my_sec_key.public_key().key);
135        let session_keys = Handshake::get_shared_secrets(
136            their_ell_swift,
137            my_ell_swift,
138            my_sec_key.key,
139            ElligatorSwiftParty::B,
140            Network::Bitcoin,
141        )?;
142        let mut packet_handler = PacketHandler::new(session_keys, Role::Responder);
143        Ok(packet_handler.reader().decrypt_payload(&payload[64+3..], None)?[1..].to_vec())
144    }
145
146    pub fn public_key(&self) -> PublicKey {
147        PublicKey{key: self.key.public_key(&secp256k1::Secp256k1::new())}
148    }
149
150    pub fn derive_usize(&self, index: usize) -> Result<Self, Error> {
151        self.get_child(Derivation::from_usize(index)?)
152    }
153
154    pub fn derive_hash(&self, hash: &Hash) -> Result<Self, Error> {
155        self.get_child(Derivation::from_hash(hash)?)
156    }
157
158    pub fn derive_bytes(&self, bytes: &[u8]) -> Result<Self, Error> {
159        self.get_child(Derivation::from_bytes(bytes)?)
160    }
161
162    pub fn get_child(&self, derivation_path: Vec<ChildNumber>) -> Result<Self, Error> {
163        let x_priv = Xpriv::new_master(
164            NetworkKind::Main,
165            &self.key.secret_bytes()
166        )?;
167        Ok(SecretKey{
168            key: x_priv.derive_priv(
169                &secp256k1::Secp256k1::new(),
170                &derivation_path,
171            )?.to_priv().inner
172        })
173    }
174}
175
176impl Default for SecretKey {
177    fn default() -> Self {Self::new()}
178}
179
180impl Ord for SecretKey {
181    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
182        self.key.secret_bytes().cmp(&other.key.secret_bytes())
183    }
184}
185
186
187impl PartialOrd for SecretKey {
188    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
189        Some(self.cmp(other))
190    }
191}
192
193impl std::fmt::Debug for SecretKey {
194    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
195        f.debug_struct("SecretKey")
196        .field("key", &&self.to_string()[0..10])
197        .field("kp", &&self.public_key().to_string()[0..10])
198        .finish()
199    }
200}
201
202impl std::fmt::Display for SecretKey {
203    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
204        write!(f, "{}", hex::encode(self.key.secret_bytes()))
205    }
206}
207
208impl std::str::FromStr for SecretKey {
209    type Err = Error;
210
211    fn from_str(s: &str) -> Result<Self, Self::Err> {
212        Ok(SecretKey{key: secp256k1::SecretKey::from_slice(&hex::decode(s)?)?})
213    }
214}
215
216impl JsonSchema for SecretKey {
217    fn schema_name() -> String {"SecretKey".to_string()}
218    fn json_schema(_gen: &mut SchemaGenerator) -> Schema {
219        Schemas::regex("^(0x|0X)?[a-fA-F0-9]{64}$".to_string())
220    }
221}
222
223struct Derivation {}
224impl Derivation {
225    pub fn from_bytes(bytes: &[u8]) -> Result<Vec<ChildNumber>, Error> {
226        let mut results = vec![];
227        for i in 0..(bytes.len()/3)+1 {
228            let index = u32::from_le_bytes([
229                bytes.get(i).copied().unwrap_or_default(),
230                bytes.get(i+1).copied().unwrap_or_default(),
231                bytes.get(i+2).copied().unwrap_or_default(),
232                0
233            ]);
234            results.push(ChildNumber::from_hardened_idx(index)?);
235        }
236        Ok(results)
237    }
238    pub fn from_usize(index: usize) -> Result<Vec<ChildNumber>, Error> {
239        Self::from_bytes(&index.to_le_bytes())
240    }
241    pub fn from_hash(hash: &Hash) -> Result<Vec<ChildNumber>, Error> {
242        Self::from_bytes(hash.as_bytes())
243    }
244}