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