cardano_sdk/cardano/crypto/ed25519/
signature.rs1use crate::{PlutusData, pallas::ed25519};
6use std::{cmp, fmt, str::FromStr};
7
8#[derive(Debug, PartialEq, Eq, Clone, Copy)]
10#[repr(transparent)]
11pub struct Signature(ed25519::Signature);
12
13impl fmt::Display for Signature {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
15 self.0.fmt(f)
16 }
17}
18
19impl PartialOrd for Signature {
20 fn partial_cmp(&self, rhs: &Self) -> Option<cmp::Ordering> {
21 Some(self.cmp(rhs))
22 }
23}
24
25impl Ord for Signature {
26 fn cmp(&self, rhs: &Self) -> cmp::Ordering {
27 let lhs = self.as_ref();
28 let rhs = rhs.as_ref();
29 lhs.cmp(rhs)
30 }
31}
32impl Signature {
35 pub const SIZE: usize = ed25519::Signature::SIZE;
36}
37
38impl From<[u8; 64]> for Signature {
41 fn from(value: [u8; 64]) -> Self {
42 Self(ed25519::Signature::from(value))
43 }
44}
45
46impl TryFrom<Vec<u8>> for Signature {
47 type Error = Vec<u8>;
48
49 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
50 Ok(Self::from(<[u8; 64]>::try_from(value)?))
51 }
52}
53
54impl FromStr for Signature {
55 type Err = anyhow::Error;
56
57 fn from_str(s: &str) -> anyhow::Result<Self> {
58 Ok(Signature(ed25519::Signature::from_str(s)?))
59 }
60}
61
62impl From<ed25519::Signature> for Signature {
63 fn from(sig: ed25519::Signature) -> Self {
64 Self(sig)
65 }
66}
67
68impl<'a> TryFrom<&PlutusData<'a>> for Signature {
69 type Error = anyhow::Error;
70
71 fn try_from(data: &PlutusData<'a>) -> anyhow::Result<Self> {
72 let array =
73 <&'_ [u8; 64]>::try_from(data).map_err(|e| e.context("invalid verification key"))?;
74 Ok(Self(ed25519::Signature::from(*array)))
75 }
76}
77
78impl<'a> TryFrom<PlutusData<'a>> for Signature {
79 type Error = anyhow::Error;
80
81 fn try_from(data: PlutusData<'a>) -> anyhow::Result<Self> {
82 Self::try_from(&data)
83 }
84}
85
86impl AsRef<[u8]> for Signature {
89 fn as_ref(&self) -> &[u8] {
90 self.0.as_ref()
91 }
92}
93
94impl From<Signature> for [u8; 64] {
95 fn from(sig: Signature) -> Self {
96 <[u8; 64]>::try_from(sig.0.as_ref())
98 .unwrap_or_else(|e| unreachable!("couldn't convert signature; not 64 bytes: {e:?}"))
99 }
100}
101
102impl From<Signature> for ed25519::Signature {
103 fn from(sig: Signature) -> Self {
104 sig.0
105 }
106}
107
108impl<'a> From<&'a Signature> for &'a ed25519::Signature {
109 fn from(sig: &'a Signature) -> Self {
110 &sig.0
111 }
112}
113
114impl<'a> From<Signature> for PlutusData<'a> {
115 fn from(key: Signature) -> Self {
116 Self::bytes(key.0)
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn test_roundtrip_fixed_array() {
126 let inner = [0; 64];
127 let sig = Signature::from(inner);
128 let re_inner = <[u8; 64]>::from(sig);
129 assert_eq!(inner, re_inner, "Failed roundtrip");
130 }
131}