1use crate::{Error, Mpint, Result};
4use core::hash::{Hash, Hasher};
5use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
6
7#[cfg(feature = "dsa")]
8use encoding::Uint;
9
10#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
14pub struct DsaPublicKey {
15 p: Mpint,
17
18 q: Mpint,
20
21 g: Mpint,
24
25 y: Mpint,
27}
28
29impl DsaPublicKey {
30 pub fn new(p: Mpint, q: Mpint, g: Mpint, y: Mpint) -> Result<Self> {
41 if p.is_positive() && q.is_positive() && g.is_positive() && y.is_positive() {
42 Ok(Self { p, q, g, y })
43 } else {
44 Err(Error::FormatEncoding)
45 }
46 }
47
48 #[must_use]
50 pub fn p(&self) -> &Mpint {
51 &self.p
52 }
53
54 #[must_use]
56 pub fn q(&self) -> &Mpint {
57 &self.q
58 }
59
60 #[must_use]
63 pub fn g(&self) -> &Mpint {
64 &self.g
65 }
66
67 #[must_use]
69 pub fn y(&self) -> &Mpint {
70 &self.y
71 }
72}
73
74impl Decode for DsaPublicKey {
75 type Error = Error;
76
77 fn decode(reader: &mut impl Reader) -> Result<Self> {
78 let p = Mpint::decode(reader)?;
79 let q = Mpint::decode(reader)?;
80 let g = Mpint::decode(reader)?;
81 let y = Mpint::decode(reader)?;
82 Self::new(p, q, g, y)
83 }
84}
85
86impl Encode for DsaPublicKey {
87 fn encoded_len(&self) -> encoding::Result<usize> {
88 [
89 self.p.encoded_len()?,
90 self.q.encoded_len()?,
91 self.g.encoded_len()?,
92 self.y.encoded_len()?,
93 ]
94 .checked_sum()
95 }
96
97 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
98 self.p.encode(writer)?;
99 self.q.encode(writer)?;
100 self.g.encode(writer)?;
101 self.y.encode(writer)
102 }
103}
104
105impl Hash for DsaPublicKey {
106 #[inline]
107 fn hash<H: Hasher>(&self, state: &mut H) {
108 self.p.as_bytes().hash(state);
109 self.q.as_bytes().hash(state);
110 self.g.as_bytes().hash(state);
111 self.y.as_bytes().hash(state);
112 }
113}
114
115#[cfg(feature = "dsa")]
116impl TryFrom<DsaPublicKey> for dsa::VerifyingKey {
117 type Error = Error;
118
119 fn try_from(key: DsaPublicKey) -> Result<dsa::VerifyingKey> {
120 dsa::VerifyingKey::try_from(&key)
121 }
122}
123
124#[cfg(feature = "dsa")]
125impl TryFrom<&DsaPublicKey> for dsa::VerifyingKey {
126 type Error = Error;
127
128 fn try_from(key: &DsaPublicKey) -> Result<dsa::VerifyingKey> {
129 let p = Uint::try_from(&key.p)?;
130 let q = Uint::try_from(&key.q)?;
131 let g = Uint::try_from(&key.g)?;
132 let y = Uint::try_from(&key.y)?;
133
134 let components = dsa::Components::from_components(p, q, g)?;
135 dsa::VerifyingKey::from_components(components, y).map_err(|_| Error::Crypto)
136 }
137}
138
139#[cfg(feature = "dsa")]
140impl From<dsa::VerifyingKey> for DsaPublicKey {
141 fn from(key: dsa::VerifyingKey) -> DsaPublicKey {
142 DsaPublicKey::from(&key)
143 }
144}
145
146#[cfg(feature = "dsa")]
147impl From<&dsa::VerifyingKey> for DsaPublicKey {
148 fn from(key: &dsa::VerifyingKey) -> DsaPublicKey {
149 DsaPublicKey {
150 p: key.components().p().as_ref().into(),
151 q: key.components().q().as_ref().into(),
152 g: key.components().g().as_ref().into(),
153 y: key.y().as_ref().into(),
154 }
155 }
156}