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> {
38 if p.is_positive() && q.is_positive() && g.is_positive() && y.is_positive() {
39 Ok(Self { p, q, g, y })
40 } else {
41 Err(Error::FormatEncoding)
42 }
43 }
44
45 pub fn p(&self) -> &Mpint {
47 &self.p
48 }
49
50 pub fn q(&self) -> &Mpint {
52 &self.q
53 }
54
55 pub fn g(&self) -> &Mpint {
58 &self.g
59 }
60
61 pub fn y(&self) -> &Mpint {
63 &self.y
64 }
65}
66
67impl Decode for DsaPublicKey {
68 type Error = Error;
69
70 fn decode(reader: &mut impl Reader) -> Result<Self> {
71 let p = Mpint::decode(reader)?;
72 let q = Mpint::decode(reader)?;
73 let g = Mpint::decode(reader)?;
74 let y = Mpint::decode(reader)?;
75 Self::new(p, q, g, y)
76 }
77}
78
79impl Encode for DsaPublicKey {
80 fn encoded_len(&self) -> encoding::Result<usize> {
81 [
82 self.p.encoded_len()?,
83 self.q.encoded_len()?,
84 self.g.encoded_len()?,
85 self.y.encoded_len()?,
86 ]
87 .checked_sum()
88 }
89
90 fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
91 self.p.encode(writer)?;
92 self.q.encode(writer)?;
93 self.g.encode(writer)?;
94 self.y.encode(writer)
95 }
96}
97
98impl Hash for DsaPublicKey {
99 #[inline]
100 fn hash<H: Hasher>(&self, state: &mut H) {
101 self.p.as_bytes().hash(state);
102 self.q.as_bytes().hash(state);
103 self.g.as_bytes().hash(state);
104 self.y.as_bytes().hash(state);
105 }
106}
107
108#[cfg(feature = "dsa")]
109impl TryFrom<DsaPublicKey> for dsa::VerifyingKey {
110 type Error = Error;
111
112 fn try_from(key: DsaPublicKey) -> Result<dsa::VerifyingKey> {
113 dsa::VerifyingKey::try_from(&key)
114 }
115}
116
117#[cfg(feature = "dsa")]
118impl TryFrom<&DsaPublicKey> for dsa::VerifyingKey {
119 type Error = Error;
120
121 fn try_from(key: &DsaPublicKey) -> Result<dsa::VerifyingKey> {
122 let p = Uint::try_from(&key.p)?;
123 let q = Uint::try_from(&key.q)?;
124 let g = Uint::try_from(&key.g)?;
125 let y = Uint::try_from(&key.y)?;
126
127 let components = dsa::Components::from_components(p, q, g)?;
128 dsa::VerifyingKey::from_components(components, y).map_err(|_| Error::Crypto)
129 }
130}
131
132#[cfg(feature = "dsa")]
133impl TryFrom<dsa::VerifyingKey> for DsaPublicKey {
134 type Error = Error;
135
136 fn try_from(key: dsa::VerifyingKey) -> Result<DsaPublicKey> {
137 DsaPublicKey::try_from(&key)
138 }
139}
140
141#[cfg(feature = "dsa")]
142impl TryFrom<&dsa::VerifyingKey> for DsaPublicKey {
143 type Error = Error;
144
145 fn try_from(key: &dsa::VerifyingKey) -> Result<DsaPublicKey> {
146 Ok(DsaPublicKey {
147 p: key.components().p().as_ref().try_into()?,
148 q: key.components().q().as_ref().try_into()?,
149 g: key.components().g().as_ref().try_into()?,
150 y: key.y().as_ref().try_into()?,
151 })
152 }
153}