1#![cfg_attr(not(feature = "std"), no_std)]
2
3extern crate alloc;
4
5use alloc::{
6 string::{String, ToString},
7 vec::Vec,
8};
9use bs58::{decode, decode::Error as Bs58DecodeError};
10use core::{convert::TryFrom, fmt::Display, str::FromStr};
11use secp256k1::{
12 schnorr::Signature, Keypair, Message as SecpMessage, Secp256k1, SecretKey, SignOnly,
13 VerifyOnly, XOnlyPublicKey,
14};
15use serde::{Deserialize, Serialize};
16
17#[derive(Debug)]
18pub enum Error {
19 Bs58Decode(Bs58DecodeError),
20 Secp256k1(secp256k1::Error),
21 KeyVersion(u16),
22 KeyLength,
23 Custom(String),
24}
25
26impl Display for Error {
27 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
28 match self {
29 Self::Bs58Decode(error) => write!(f, "Base58 code error: {error}"),
30 Self::Secp256k1(error) => write!(f, "Secp256k1 error: {error}"),
31 Self::KeyVersion(obtained) => {
32 write!(f, "Unknown public key version. version found: {obtained}")
33 }
34 Self::KeyLength => write!(f, "Bad key length"),
35 Self::Custom(error) => write!(f, "Custom error: {error}"),
36 }
37 }
38}
39
40#[cfg(feature = "std")]
41impl std::error::Error for Error {}
42#[cfg(not(feature = "std"))]
43#[rustversion::since(1.81)]
44impl core::error::Error for Error {}
45
46impl From<Bs58DecodeError> for Error {
47 fn from(e: Bs58DecodeError) -> Self {
48 Error::Bs58Decode(e)
49 }
50}
51
52impl From<secp256k1::Error> for Error {
53 fn from(e: secp256k1::Error) -> Self {
54 Error::Secp256k1(e)
55 }
56}
57
58#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
59#[serde(into = "String", try_from = "String")]
60pub struct Secp256k1SecretKey(pub SecretKey);
61
62impl TryFrom<String> for Secp256k1SecretKey {
63 type Error = Error;
64
65 fn try_from(value: String) -> Result<Self, Self::Error> {
66 value.parse()
67 }
68}
69
70impl FromStr for Secp256k1SecretKey {
71 type Err = Error;
72
73 fn from_str(value: &str) -> Result<Self, Self::Err> {
74 let decoded = decode(value).with_check(None).into_vec()?;
75 let secret = SecretKey::from_slice(&decoded)?;
76 Ok(Secp256k1SecretKey(secret))
77 }
78}
79
80impl From<Secp256k1SecretKey> for String {
81 fn from(secret: Secp256k1SecretKey) -> Self {
82 secret.to_string()
83 }
84}
85
86impl Display for Secp256k1SecretKey {
87 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
88 let bytes = self.0.secret_bytes();
89 f.write_str(&bs58::encode(bytes).with_check().into_string())
90 }
91}
92
93#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
94#[serde(into = "String", try_from = "String")]
95pub struct Secp256k1PublicKey(pub XOnlyPublicKey);
96
97impl TryFrom<String> for Secp256k1PublicKey {
98 type Error = Error;
99
100 fn try_from(value: String) -> Result<Self, Self::Error> {
101 value.parse()
102 }
103}
104
105impl FromStr for Secp256k1PublicKey {
106 type Err = Error;
107
108 fn from_str(value: &str) -> Result<Self, Self::Err> {
109 let decoded = decode(value).with_check(None).into_vec()?;
110 if decoded.len() < 34 {
111 return Err(Error::KeyLength);
112 }
113 let key_version =
114 u16::from_le_bytes(decoded[..2].try_into().expect("Invalid array length"));
115 if key_version != 1 {
116 return Err(Error::KeyVersion(key_version));
117 }
118 let public = XOnlyPublicKey::from_slice(&decoded[2..]).map_err(Error::Secp256k1)?;
119 Ok(Secp256k1PublicKey(public))
120 }
121}
122
123impl From<Secp256k1PublicKey> for String {
124 fn from(public: Secp256k1PublicKey) -> Self {
125 public.to_string()
126 }
127}
128
129impl Display for Secp256k1PublicKey {
130 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
131 let mut output = [0_u8; 34];
132 output[0] = 1;
133 let bytes = self.0.serialize();
134 output[2..].copy_from_slice(&bytes);
135 f.write_str(&bs58::encode(&output).with_check().into_string())
136 }
137}
138
139impl Secp256k1PublicKey {
140 pub fn into_bytes(self) -> [u8; 32] {
141 self.0.serialize()
142 }
143}
144impl Secp256k1SecretKey {
145 pub fn into_bytes(self) -> [u8; 32] {
146 self.0.secret_bytes()
147 }
148}
149
150impl From<Secp256k1SecretKey> for Secp256k1PublicKey {
151 fn from(value: Secp256k1SecretKey) -> Self {
152 let context = secp256k1::Secp256k1::new();
153 let (x_coordinate, _) = value.0.public_key(&context).x_only_public_key();
154 Self(x_coordinate)
155 }
156}
157
158pub struct SignatureService {
159 secp_sign: Secp256k1<SignOnly>,
160 secp_verify: Secp256k1<VerifyOnly>,
161}
162
163impl SignatureService {
164 pub fn new() -> Self {
165 SignatureService {
166 secp_sign: Secp256k1::signing_only(),
167 secp_verify: Secp256k1::verification_only(),
168 }
169 }
170
171 #[cfg(feature = "std")]
172 pub fn sign(&self, message: Vec<u8>, private_key: SecretKey) -> Signature {
173 self.sign_with_rng(message, private_key, &mut rand::thread_rng())
174 }
175
176 #[inline]
177 pub fn sign_with_rng<R: rand::Rng + rand::CryptoRng>(
178 &self,
179 message: Vec<u8>,
180 private_key: SecretKey,
181 rng: &mut R,
182 ) -> Signature {
183 let secret_key = private_key;
184 let kp = Keypair::from_secret_key(&self.secp_sign, &secret_key);
185
186 self.secp_sign.sign_schnorr_with_rng(
187 &SecpMessage::from_digest_slice(&message).unwrap(),
188 &kp,
189 rng,
190 )
191 }
192
193 pub fn verify(
194 &self,
195 message: Vec<u8>,
196 signature: secp256k1::schnorr::Signature,
197 public_key: XOnlyPublicKey,
198 ) -> Result<(), secp256k1::Error> {
199 let x_only_public_key = public_key;
200
201 self.secp_verify.verify_schnorr(
203 &signature,
204 &secp256k1::Message::from_digest_slice(&message)?,
205 &x_only_public_key,
206 )
207 }
208}
209
210impl Default for SignatureService {
211 fn default() -> Self {
212 Self::new()
213 }
214}
215
216#[cfg(test)]
217mod test {
218 use super::*;
219
220 #[test]
221 fn key_conversions() {
222 let secret_key = "zmBEmPhqo3A92FkiLVvyCz6htc3e53ph3ZbD4ASqGaLjwnFLi";
223 let public_key = "9bDuixKmZqAJnrmP746n8zU1wyAQRrus7th9dxnkPg6RzQvCnan";
224 let bad_public_key1 = "9bDuixKmZqAJnrmP746n8zU1wyAQRrus7th9dxnkPg6RzQvCnam"; let bad_public_key2 = "2myPhc5vkPzuC5FXNK5tee79WmP7uoLh55SxezoF8iqwF3E3rnPY"; let bad_public_key3 = "2wmHTKZkLg2QzXyEXGMBXzKP7JXDUt8yy9SA5hoQwERc92qR6c"; let error = bad_public_key1
229 .parse::<Secp256k1PublicKey>()
230 .expect_err("Bad bud public key failed to raise error");
231 assert!(
232 matches!(error, Error::Bs58Decode(_)),
233 "expected failed checksum error, got {}",
234 error
235 );
236 let error = bad_public_key2
237 .parse::<Secp256k1PublicKey>()
238 .expect_err("Bad bud public key failed to raise error");
239 assert!(
240 matches!(error, Error::KeyVersion(_)),
241 "expected invalid key version error, got {}",
242 error
243 );
244 let error = bad_public_key3
245 .parse::<Secp256k1PublicKey>()
246 .expect_err("Bad bud public key failed to raise error");
247 assert!(
248 matches!(error, Error::KeyLength),
249 "expected invalid key length error, got {}",
250 error
251 );
252
253 let parsed_key = secret_key
254 .parse::<Secp256k1SecretKey>()
255 .expect("Invalid test key");
256
257 let calculated_public_key = Secp256k1PublicKey::from(parsed_key);
258 assert_eq!(calculated_public_key.to_string(), public_key);
259
260 let parsed_public_key = public_key
261 .parse::<Secp256k1PublicKey>()
262 .expect("Invalid test pubkey");
263 assert_eq!(calculated_public_key.0, parsed_public_key.0);
264 }
265}