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}