1use crate::{EcdsaCurve, Error, Result};
7use core::{
8 fmt::{self, Debug},
9 ops::{Add, Range},
10};
11use der::{
12 Decode, DecodeValue, Encode, EncodeValue, FixedTag, Header, Length, Reader, Sequence, Tag,
13 Writer, asn1::UintRef,
14};
15use elliptic_curve::{
16 FieldBytesSize,
17 array::{Array, ArraySize, typenum::Unsigned},
18 consts::U9,
19};
20
21#[cfg(feature = "alloc")]
22use {
23 alloc::{boxed::Box, vec::Vec},
24 signature::SignatureEncoding,
25 spki::{SignatureBitStringEncoding, der::asn1::BitString},
26};
27
28#[cfg(feature = "serde")]
29use serdect::serde::{Deserialize, Serialize, de, ser};
30
31pub type MaxOverhead = U9;
46
47pub type MaxSize<C> = <<FieldBytesSize<C> as Add>::Output as Add<MaxOverhead>>::Output;
49
50type SignatureBytes<C> = Array<u8, MaxSize<C>>;
52
53pub struct Signature<C>
64where
65 C: EcdsaCurve,
66 MaxSize<C>: ArraySize,
67 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
68{
69 bytes: SignatureBytes<C>,
71
72 r_range: Range<usize>,
74
75 s_range: Range<usize>,
77}
78
79#[allow(clippy::len_without_is_empty)]
80impl<C> Signature<C>
81where
82 C: EcdsaCurve,
83 MaxSize<C>: ArraySize,
84 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
85{
86 pub fn from_bytes(input: &[u8]) -> Result<Self> {
91 let SignatureRef { r, s } = SignatureRef::from_der(input).map_err(|_| Error::new())?;
92
93 if r.as_bytes().len() > C::FieldBytesSize::USIZE
94 || s.as_bytes().len() > C::FieldBytesSize::USIZE
95 {
96 return Err(Error::new());
97 }
98
99 let r_range = find_scalar_range(input, r.as_bytes())?;
100 let s_range = find_scalar_range(input, s.as_bytes())?;
101
102 if s_range.end != input.len() {
103 return Err(Error::new());
104 }
105
106 let mut bytes = SignatureBytes::<C>::default();
107 bytes[..s_range.end].copy_from_slice(input);
108
109 Ok(Signature {
110 bytes,
111 r_range,
112 s_range,
113 })
114 }
115
116 pub(crate) fn from_components(r: &[u8], s: &[u8]) -> der::Result<Self> {
118 let sig = SignatureRef {
119 r: UintRef::new(r)?,
120 s: UintRef::new(s)?,
121 };
122 let mut bytes = SignatureBytes::<C>::default();
123
124 sig.encode_to_slice(&mut bytes)?
125 .try_into()
126 .map_err(|_| Tag::Sequence.value_error().into())
127 }
128
129 pub fn as_bytes(&self) -> &[u8] {
131 &self.bytes.as_slice()[..self.len()]
132 }
133
134 #[cfg(feature = "alloc")]
136 pub fn to_bytes(&self) -> Box<[u8]> {
137 self.as_bytes().to_vec().into_boxed_slice()
138 }
139
140 pub fn len(&self) -> usize {
142 self.s_range.end
143 }
144
145 pub(crate) fn r(&self) -> &[u8] {
147 &self.bytes[self.r_range.clone()]
148 }
149
150 pub(crate) fn s(&self) -> &[u8] {
152 &self.bytes[self.s_range.clone()]
153 }
154}
155
156impl<C> core::hash::Hash for Signature<C>
157where
158 C: EcdsaCurve,
159 MaxSize<C>: ArraySize,
160 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
161{
162 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
163 self.as_bytes().hash(state);
164 }
165}
166
167impl<C> AsRef<[u8]> for Signature<C>
168where
169 C: EcdsaCurve,
170 MaxSize<C>: ArraySize,
171 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
172{
173 fn as_ref(&self) -> &[u8] {
174 self.as_bytes()
175 }
176}
177
178impl<C> Clone for Signature<C>
179where
180 C: EcdsaCurve,
181 MaxSize<C>: ArraySize,
182 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
183{
184 fn clone(&self) -> Self {
185 Self {
186 bytes: self.bytes.clone(),
187 r_range: self.r_range.clone(),
188 s_range: self.s_range.clone(),
189 }
190 }
191}
192
193impl<C> Debug for Signature<C>
194where
195 C: EcdsaCurve,
196 MaxSize<C>: ArraySize,
197 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
198{
199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
200 write!(f, "ecdsa::der::Signature<{:?}>(", C::default())?;
201
202 for &byte in self.as_ref() {
203 write!(f, "{byte:02X}")?;
204 }
205
206 write!(f, ")")
207 }
208}
209
210impl<'a, C> Decode<'a> for Signature<C>
211where
212 C: EcdsaCurve,
213 MaxSize<C>: ArraySize,
214 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
215{
216 type Error = der::Error;
217
218 fn decode<R: Reader<'a>>(reader: &mut R) -> der::Result<Self> {
219 let header = Header::peek(reader)?;
220 header.tag().assert_eq(Tag::Sequence)?;
221
222 let mut buf = SignatureBytes::<C>::default();
223 let len = (header.encoded_len()? + header.length())?;
224 let slice = buf
225 .get_mut(..usize::try_from(len)?)
226 .ok_or_else(|| reader.error(Tag::Sequence.length_error()))?;
227
228 reader.read_into(slice)?;
229 Self::from_bytes(slice).map_err(|_| reader.error(Tag::Integer.value_error()))
230 }
231}
232
233impl<C> Encode for Signature<C>
234where
235 C: EcdsaCurve,
236 MaxSize<C>: ArraySize,
237 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
238{
239 fn encoded_len(&self) -> der::Result<Length> {
240 Length::try_from(self.len())
241 }
242
243 fn encode(&self, writer: &mut impl Writer) -> der::Result<()> {
244 writer.write(self.as_bytes())
245 }
246}
247
248impl<C> FixedTag for Signature<C>
249where
250 C: EcdsaCurve,
251 MaxSize<C>: ArraySize,
252 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
253{
254 const TAG: Tag = Tag::Sequence;
255}
256
257impl<C> From<crate::Signature<C>> for Signature<C>
258where
259 C: EcdsaCurve,
260 MaxSize<C>: ArraySize,
261 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
262{
263 fn from(sig: crate::Signature<C>) -> Signature<C> {
264 sig.to_der()
265 }
266}
267
268impl<C> TryFrom<&[u8]> for Signature<C>
269where
270 C: EcdsaCurve,
271 MaxSize<C>: ArraySize,
272 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
273{
274 type Error = Error;
275
276 fn try_from(input: &[u8]) -> Result<Self> {
277 Self::from_bytes(input)
278 }
279}
280
281impl<C> TryFrom<Signature<C>> for crate::Signature<C>
282where
283 C: EcdsaCurve,
284 MaxSize<C>: ArraySize,
285 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
286{
287 type Error = Error;
288
289 fn try_from(sig: Signature<C>) -> Result<super::Signature<C>> {
290 let mut bytes = super::SignatureBytes::<C>::default();
291 let r_begin = C::FieldBytesSize::USIZE.saturating_sub(sig.r().len());
292 let s_begin = bytes.len().saturating_sub(sig.s().len());
293 bytes[r_begin..C::FieldBytesSize::USIZE].copy_from_slice(sig.r());
294 bytes[s_begin..].copy_from_slice(sig.s());
295 Self::try_from(bytes.as_slice())
296 }
297}
298
299#[cfg(feature = "alloc")]
300impl<C> From<Signature<C>> for Box<[u8]>
301where
302 C: EcdsaCurve,
303 MaxSize<C>: ArraySize,
304 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
305{
306 fn from(signature: Signature<C>) -> Box<[u8]> {
307 signature.to_vec().into_boxed_slice()
308 }
309}
310
311#[cfg(feature = "alloc")]
312impl<C> SignatureEncoding for Signature<C>
313where
314 C: EcdsaCurve,
315 MaxSize<C>: ArraySize,
316 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
317{
318 type Repr = Box<[u8]>;
319
320 fn to_vec(&self) -> Vec<u8> {
321 self.as_bytes().into()
322 }
323}
324
325#[cfg(feature = "alloc")]
326impl<C> SignatureBitStringEncoding for Signature<C>
327where
328 C: EcdsaCurve,
329 MaxSize<C>: ArraySize,
330 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
331{
332 fn to_bitstring(&self) -> der::Result<BitString> {
333 BitString::new(0, self.to_vec())
334 }
335}
336
337#[cfg(feature = "serde")]
338impl<C> Serialize for Signature<C>
339where
340 C: EcdsaCurve,
341 MaxSize<C>: ArraySize,
342 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
343{
344 fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
345 where
346 S: ser::Serializer,
347 {
348 serdect::slice::serialize_hex_upper_or_bin(&self.as_bytes(), serializer)
349 }
350}
351
352#[cfg(feature = "serde")]
353impl<'de, C> Deserialize<'de> for Signature<C>
354where
355 C: EcdsaCurve,
356 MaxSize<C>: ArraySize,
357 <FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
358{
359 fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
360 where
361 D: de::Deserializer<'de>,
362 {
363 let mut buf = SignatureBytes::<C>::default();
364 let slice = serdect::slice::deserialize_hex_or_bin(&mut buf, deserializer)?;
365 Self::try_from(slice).map_err(de::Error::custom)
366 }
367}
368
369struct SignatureRef<'a> {
370 pub r: UintRef<'a>,
371 pub s: UintRef<'a>,
372}
373
374impl EncodeValue for SignatureRef<'_> {
375 fn value_len(&self) -> der::Result<Length> {
376 self.r.encoded_len()? + self.s.encoded_len()?
377 }
378
379 fn encode_value(&self, encoder: &mut impl Writer) -> der::Result<()> {
380 self.r.encode(encoder)?;
381 self.s.encode(encoder)?;
382 Ok(())
383 }
384}
385
386impl<'a> DecodeValue<'a> for SignatureRef<'a> {
387 type Error = der::Error;
388
389 fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> der::Result<Self> {
390 Ok(Self {
391 r: UintRef::decode(reader)?,
392 s: UintRef::decode(reader)?,
393 })
394 }
395}
396impl<'a> Sequence<'a> for SignatureRef<'a> {}
397
398#[allow(clippy::as_conversions)]
400fn find_scalar_range(outer: &[u8], inner: &[u8]) -> Result<Range<usize>> {
401 let outer_start = outer.as_ptr() as usize;
402 let inner_start = inner.as_ptr() as usize;
403 let start = inner_start
404 .checked_sub(outer_start)
405 .ok_or_else(Error::new)?;
406 let end = start.checked_add(inner.len()).ok_or_else(Error::new)?;
407 Ok(Range { start, end })
408}
409
410#[cfg(all(test, feature = "algorithm"))]
411mod tests {
412 use elliptic_curve::dev::MockCurve;
413
414 type Signature = crate::Signature<MockCurve>;
415
416 const EXAMPLE_SIGNATURE: [u8; 64] = [
417 0xf3, 0xac, 0x80, 0x61, 0xb5, 0x14, 0x79, 0x5b, 0x88, 0x43, 0xe3, 0xd6, 0x62, 0x95, 0x27,
418 0xed, 0x2a, 0xfd, 0x6b, 0x1f, 0x6a, 0x55, 0x5a, 0x7a, 0xca, 0xbb, 0x5e, 0x6f, 0x79, 0xc8,
419 0xc2, 0xac, 0x8b, 0xf7, 0x78, 0x19, 0xca, 0x5, 0xa6, 0xb2, 0x78, 0x6c, 0x76, 0x26, 0x2b,
420 0xf7, 0x37, 0x1c, 0xef, 0x97, 0xb2, 0x18, 0xe9, 0x6f, 0x17, 0x5a, 0x3c, 0xcd, 0xda, 0x2a,
421 0xcc, 0x5, 0x89, 0x3,
422 ];
423
424 #[test]
425 fn test_fixed_to_asn1_signature_roundtrip() {
426 let signature1 =
427 Signature::try_from(EXAMPLE_SIGNATURE.as_ref()).expect("decoded Signature");
428
429 let asn1_signature = signature1.to_der();
431 let signature2 = Signature::from_der(asn1_signature.as_ref()).expect("decoded Signature");
432
433 assert_eq!(signature1, signature2);
434 }
435
436 #[test]
437 fn test_asn1_too_short_signature() {
438 assert!(Signature::from_der(&[]).is_err());
439 assert!(Signature::from_der(&[0x30]).is_err());
440 assert!(Signature::from_der(&[0x30, 0x00]).is_err());
441 assert!(Signature::from_der(&[0x30, 0x03, 0x02, 0x01, 0x01]).is_err());
442 }
443
444 #[test]
445 fn test_asn1_non_der_signature() {
446 assert!(
448 Signature::from_der(&[
449 0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, ])
458 .is_ok()
459 );
460
461 assert!(
465 Signature::from_der(&[
466 0x30, 0x81, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, ])
476 .is_err()
477 );
478 }
479}