1use core::fmt::{Debug, Display, Formatter, Result as FmtResult};
2use serde::{
3 de::{self, Visitor},
4 Deserialize, Deserializer, Serialize, Serializer,
5};
6use std::{array::TryFromSliceError, hash::Hash};
7
8use crate::_rename::{
9 secp256k1_ecdsa_sign, secp256k1_ecdsa_signature_parse_compact,
10 secp256k1_ecdsa_signature_serialize_compact, secp256k1_ecdsa_verify,
11};
12use crate::{
13 bindings::secp256k1_ecdsa_signature, context::Context, errors::ConversionError, scalar::Scalar,
14};
15
16pub use crate::keys::{Error as KeyError, PublicKey};
17
18#[derive(Debug, Clone)]
19pub enum Error {
21 Key(KeyError),
23 TryFrom(String),
25 Conversion(ConversionError),
27}
28
29impl Display for Error {
30 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
31 write!(f, "{:?}", self)
32 }
33}
34
35impl std::error::Error for Error {}
36
37impl From<TryFromSliceError> for Error {
38 fn from(e: TryFromSliceError) -> Self {
39 Error::TryFrom(e.to_string())
40 }
41}
42
43#[derive(Debug, Clone)]
47pub struct Signature {
48 pub signature: secp256k1_ecdsa_signature,
50}
51
52impl Signature {
53 pub fn new(hash: &[u8], sec_key: &Scalar) -> Result<Self, Error> {
55 let context = Context::default();
56 let mut sig = Self {
57 signature: secp256k1_ecdsa_signature { data: [0; 64] },
58 };
59 if unsafe {
60 secp256k1_ecdsa_sign(
61 context.context,
62 &mut sig.signature,
63 hash.as_ptr(),
64 sec_key.to_bytes().as_ptr(),
65 None,
66 std::ptr::null_mut::<::std::os::raw::c_void>(),
67 )
68 } == 0
69 {
70 return Err(Error::Key(KeyError::InvalidSecretKey));
71 }
72 Ok(sig)
73 }
74
75 pub fn verify(&self, hash: &[u8], pub_key: &PublicKey) -> bool {
77 let context = Context::default();
78
79 1 == unsafe {
80 secp256k1_ecdsa_verify(
81 context.context,
82 &self.signature,
83 hash.as_ptr(),
84 &pub_key.key,
85 )
86 }
87 }
88
89 pub fn to_bytes(&self) -> [u8; 64] {
91 let context = Context::default();
92 let mut bytes = [0u8; 64];
93 unsafe {
95 secp256k1_ecdsa_signature_serialize_compact(
96 context.context,
97 bytes.as_mut_ptr(),
98 &self.signature,
99 );
100 }
101 bytes
102 }
103}
104
105impl Display for Signature {
106 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
107 write!(f, "{}", bs58::encode(self.to_bytes()).into_string())
108 }
109}
110
111impl PartialEq for Signature {
112 fn eq(&self, other: &Self) -> bool {
113 self.to_bytes().eq(&other.to_bytes())
114 }
115}
116
117impl Eq for Signature {}
118
119impl PartialOrd for Signature {
120 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
121 Some(self.cmp(other))
122 }
123}
124
125impl Ord for Signature {
126 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
127 self.to_bytes().cmp(&other.to_bytes())
128 }
129}
130
131impl Hash for Signature {
132 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
133 state.write(&self.to_bytes())
134 }
135}
136
137impl Serialize for Signature {
138 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
139 where
140 S: Serializer,
141 {
142 serializer.serialize_bytes(&self.to_bytes())
143 }
144}
145
146struct SignatureVisitor;
147
148impl<'de> Visitor<'de> for SignatureVisitor {
149 type Value = Signature;
150
151 fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
152 formatter.write_str("an array of bytes which represents two scalars on the secp256k1 curve")
153 }
154
155 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
156 where
157 E: de::Error,
158 {
159 match Signature::try_from(value) {
160 Ok(s) => Ok(s),
161 Err(e) => Err(E::custom(format!("{:?}", e))),
162 }
163 }
164
165 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
166 where
167 A: de::SeqAccess<'de>,
168 {
169 let mut v = Vec::new();
170
171 while let Ok(Some(x)) = seq.next_element() {
172 v.push(x);
173 }
174
175 self.visit_bytes(&v)
176 }
177}
178
179impl<'de> Deserialize<'de> for Signature {
180 fn deserialize<D>(deserializer: D) -> Result<Signature, D::Error>
181 where
182 D: Deserializer<'de>,
183 {
184 deserializer.deserialize_bytes(SignatureVisitor)
185 }
186}
187
188impl TryFrom<&[u8]> for Signature {
189 type Error = Error;
190 fn try_from(input: &[u8]) -> Result<Self, Self::Error> {
193 let data: [u8; 64] = input[0..].try_into()?;
194 Signature::try_from(data)
195 }
196}
197
198impl TryFrom<[u8; 64]> for Signature {
199 type Error = Error;
200 fn try_from(input: [u8; 64]) -> Result<Self, Self::Error> {
203 let context = Context::default();
204 let mut sig = Self {
205 signature: secp256k1_ecdsa_signature { data: [0u8; 64] },
206 };
207 let parsed = unsafe {
209 secp256k1_ecdsa_signature_parse_compact(
210 context.context,
211 &mut sig.signature,
212 input.as_ptr(),
213 )
214 };
215 if parsed == 0 {
216 return Err(Error::TryFrom(
217 "Failed to serialize input data into compact (64 byte) form.".to_string(),
218 ));
219 }
220 Ok(sig)
221 }
222}
223
224#[cfg(test)]
225mod tests {
226 use super::*;
227 use rand_core::{OsRng, RngCore};
228 use sha2::{Digest, Sha256};
229 use std::{collections::HashSet, thread};
230
231 #[test]
232 fn signature_generation() {
233 let mut rnd = OsRng::default();
235 let sec_key = Scalar::random(&mut rnd);
236 let pub_key = PublicKey::new(&sec_key).unwrap();
237
238 let msg = b"Hello, world!";
240 let mut hasher = Sha256::new();
241 hasher.update(msg);
242 let msg_hash = hasher.finalize();
243 let sig = Signature::new(&msg_hash, &sec_key).unwrap();
245
246 assert!(sig.verify(&msg_hash, &pub_key));
248 }
249
250 #[test]
251 fn signature_generation_threaded() {
252 let mut rnd = OsRng::default();
254 let sec_key = Scalar::random(&mut rnd);
255 let pub_key = PublicKey::new(&sec_key).unwrap();
256
257 let msg = b"Hello, world!";
259 let mut hasher = Sha256::new();
260 hasher.update(msg);
261 let msg_hash = hasher.finalize();
262
263 let mut handles = Vec::new();
264 for _ in 0..64 {
265 let sec_key = sec_key.clone();
266 let pub_key = pub_key.clone();
267 let msg_hash = msg_hash.clone();
268 handles.push(thread::spawn(move || {
269 let sig = Signature::new(&msg_hash, &sec_key).unwrap();
271
272 assert!(sig.verify(&msg_hash, &pub_key));
274 }));
275 }
276
277 for handle in handles {
278 handle.join().unwrap();
279 }
280 }
281
282 #[test]
283 fn signature_from() {
284 let mut rng = OsRng::default();
286 let mut bytes = [0u8; 64];
287 rng.fill_bytes(&mut bytes);
288
289 let sig_from_struct = Signature {
290 signature: secp256k1_ecdsa_signature { data: bytes },
291 };
292 let sig_from_slice = Signature::try_from(bytes.as_slice()).unwrap();
293 let sig_from_array = Signature::try_from(bytes).unwrap();
294
295 assert_ne!(sig_from_struct.to_bytes(), sig_from_slice.to_bytes());
296 assert_ne!(sig_from_struct.to_bytes(), sig_from_array.to_bytes());
297 assert_eq!(sig_from_array.to_bytes(), sig_from_slice.to_bytes());
298
299 let mut too_small = [0u8; 63];
300 rng.fill_bytes(&mut too_small);
301 assert!(Signature::try_from(too_small.as_slice()).is_err());
302
303 let mut too_big = [0u8; 65];
304 rng.fill_bytes(&mut too_big);
305 assert!(Signature::try_from(too_big.as_slice()).is_err());
306 }
307
308 #[test]
309 fn manual_serde() {
310 let mut rng = OsRng::default();
312 let mut bytes = [0u8; 64];
313 rng.fill_bytes(&mut bytes);
314
315 let sig = Signature::try_from(bytes).unwrap();
317 assert_ne!(sig.signature.data, bytes);
318 assert_eq!(sig.to_bytes(), bytes);
319 }
320
321 #[test]
322 fn custom_serde() {
323 let mut rng = OsRng::default();
324 let mut hash = [0u8; 32];
325 rng.fill_bytes(&mut hash);
326 let private_key = Scalar::random(&mut rng);
327 let public_key = PublicKey::new(&private_key).expect("failed to create public key");
328 let sig = Signature::new(&hash, &private_key).expect("failed to create sig");
329
330 assert!(sig.verify(&hash, &public_key));
331
332 let ssig = serde_json::to_string(&sig).expect("failed to serialize");
333 let dsig: Signature = serde_json::from_str(&ssig).expect("failed to deserialize");
334
335 assert!(dsig.verify(&hash, &public_key));
336 }
337
338 #[test]
339 fn hash() {
340 let msg = [0u8; 32];
341 let private_keys = [1, 2, 3, 4, 5].map(Scalar::from);
342 let signatures = private_keys.map(|pk| Signature::new(&msg, &pk).unwrap());
343
344 let signatures_hash_set: HashSet<_> = signatures.into();
345
346 assert_eq!(signatures_hash_set.len(), 5);
347 }
348
349 #[test]
350 fn sort() {
351 let msg = [0u8; 32];
352 let private_keys = [1, 2, 3, 4, 5].map(Scalar::from);
353 let mut signatures = private_keys.map(|pk| Signature::new(&msg, &pk).unwrap());
354 signatures.sort();
355
356 for idx in 0..4 {
357 assert!(signatures[idx] < signatures[idx + 1]);
358 }
359 }
360}