dsa/
components.rs

1//!
2//! Module containing the definition of the common components container
3//!
4
5use crate::{size::KeySize, two};
6use num_bigint::BigUint;
7use num_traits::Zero;
8use pkcs8::der::{
9    self, asn1::UintRef, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Tag,
10    Writer,
11};
12use signature::rand_core::CryptoRngCore;
13
14/// The common components of an DSA keypair
15///
16/// (the prime p, quotient q and generator g)
17#[derive(Clone, Debug, PartialEq, PartialOrd)]
18#[must_use]
19pub struct Components {
20    /// Prime p
21    p: BigUint,
22
23    /// Quotient q
24    q: BigUint,
25
26    /// Generator g
27    g: BigUint,
28}
29
30impl Components {
31    /// Construct the common components container from its inner values (p, q and g)
32    pub fn from_components(p: BigUint, q: BigUint, g: BigUint) -> signature::Result<Self> {
33        if p < two() || q < two() || g.is_zero() || g > p {
34            return Err(signature::Error::new());
35        }
36
37        Ok(Self { p, q, g })
38    }
39
40    /// Generate a new pair of common components
41    pub fn generate(rng: &mut impl CryptoRngCore, key_size: KeySize) -> Self {
42        let (p, q, g) = crate::generate::common_components(rng, key_size);
43        Self::from_components(p, q, g).expect("[Bug] Newly generated components considered invalid")
44    }
45
46    /// DSA prime p
47    #[must_use]
48    pub const fn p(&self) -> &BigUint {
49        &self.p
50    }
51
52    /// DSA quotient q
53    #[must_use]
54    pub const fn q(&self) -> &BigUint {
55        &self.q
56    }
57
58    /// DSA generator g
59    #[must_use]
60    pub const fn g(&self) -> &BigUint {
61        &self.g
62    }
63}
64
65impl<'a> DecodeValue<'a> for Components {
66    fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> der::Result<Self> {
67        let p = reader.decode::<UintRef<'_>>()?;
68        let q = reader.decode::<UintRef<'_>>()?;
69        let g = reader.decode::<UintRef<'_>>()?;
70
71        let p = BigUint::from_bytes_be(p.as_bytes());
72        let q = BigUint::from_bytes_be(q.as_bytes());
73        let g = BigUint::from_bytes_be(g.as_bytes());
74
75        Self::from_components(p, q, g).map_err(|_| Tag::Integer.value_error())
76    }
77}
78
79impl EncodeValue for Components {
80    fn value_len(&self) -> der::Result<Length> {
81        UintRef::new(&self.p.to_bytes_be())?.encoded_len()?
82            + UintRef::new(&self.q.to_bytes_be())?.encoded_len()?
83            + UintRef::new(&self.g.to_bytes_be())?.encoded_len()?
84    }
85
86    fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> {
87        UintRef::new(&self.p.to_bytes_be())?.encode(writer)?;
88        UintRef::new(&self.q.to_bytes_be())?.encode(writer)?;
89        UintRef::new(&self.g.to_bytes_be())?.encode(writer)?;
90        Ok(())
91    }
92}
93
94impl<'a> Sequence<'a> for Components {}