use crate::{
checked::CheckedSum, decode::Decode, encode::Encode, public::DsaPublicKey, reader::Reader,
writer::Writer, MPInt, Result,
};
use core::fmt;
use zeroize::Zeroize;
#[cfg(feature = "subtle")]
use subtle::{Choice, ConstantTimeEq};
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
#[derive(Clone)]
pub struct DsaPrivateKey {
inner: MPInt,
}
impl DsaPrivateKey {
pub fn as_bytes(&self) -> &[u8] {
self.inner.as_bytes()
}
pub fn as_mpint(&self) -> &MPInt {
&self.inner
}
}
impl AsRef<[u8]> for DsaPrivateKey {
fn as_ref(&self) -> &[u8] {
self.as_bytes()
}
}
impl Decode for DsaPrivateKey {
fn decode(reader: &mut impl Reader) -> Result<Self> {
Ok(Self {
inner: MPInt::decode(reader)?,
})
}
}
impl Drop for DsaPrivateKey {
fn drop(&mut self) {
self.inner.zeroize();
}
}
impl Encode for DsaPrivateKey {
fn encoded_len(&self) -> Result<usize> {
self.inner.encoded_len()
}
fn encode(&self, writer: &mut impl Writer) -> Result<()> {
self.inner.encode(writer)
}
}
impl fmt::Debug for DsaPrivateKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DsaPrivateKey").finish_non_exhaustive()
}
}
#[cfg(feature = "subtle")]
#[cfg_attr(docsrs, doc(cfg(feature = "subtle")))]
impl ConstantTimeEq for DsaPrivateKey {
fn ct_eq(&self, other: &Self) -> Choice {
self.inner.ct_eq(&other.inner)
}
}
#[cfg(feature = "subtle")]
#[cfg_attr(docsrs, doc(cfg(feature = "subtle")))]
impl PartialEq for DsaPrivateKey {
fn eq(&self, other: &Self) -> bool {
self.ct_eq(other).into()
}
}
#[cfg(feature = "subtle")]
#[cfg_attr(docsrs, doc(cfg(feature = "subtle")))]
impl Eq for DsaPrivateKey {}
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
#[derive(Clone)]
pub struct DsaKeypair {
pub public: DsaPublicKey,
pub private: DsaPrivateKey,
}
impl Decode for DsaKeypair {
fn decode(reader: &mut impl Reader) -> Result<Self> {
let public = DsaPublicKey::decode(reader)?;
let private = DsaPrivateKey::decode(reader)?;
Ok(DsaKeypair { public, private })
}
}
impl Encode for DsaKeypair {
fn encoded_len(&self) -> Result<usize> {
[self.public.encoded_len()?, self.private.encoded_len()?].checked_sum()
}
fn encode(&self, writer: &mut impl Writer) -> Result<()> {
self.public.encode(writer)?;
self.private.encode(writer)
}
}
impl From<DsaKeypair> for DsaPublicKey {
fn from(keypair: DsaKeypair) -> DsaPublicKey {
keypair.public
}
}
impl From<&DsaKeypair> for DsaPublicKey {
fn from(keypair: &DsaKeypair) -> DsaPublicKey {
keypair.public.clone()
}
}
impl fmt::Debug for DsaKeypair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DsaKeypair")
.field("public", &self.public)
.finish_non_exhaustive()
}
}
#[cfg(feature = "subtle")]
#[cfg_attr(docsrs, doc(cfg(feature = "subtle")))]
impl ConstantTimeEq for DsaKeypair {
fn ct_eq(&self, other: &Self) -> Choice {
Choice::from((self.public == other.public) as u8) & self.private.ct_eq(&other.private)
}
}
#[cfg(feature = "subtle")]
#[cfg_attr(docsrs, doc(cfg(feature = "subtle")))]
impl PartialEq for DsaKeypair {
fn eq(&self, other: &Self) -> bool {
self.ct_eq(other).into()
}
}
#[cfg(feature = "subtle")]
#[cfg_attr(docsrs, doc(cfg(feature = "subtle")))]
impl Eq for DsaKeypair {}