dsa: rename key types to SigningKey and VerifyingKey (#485)

For consistency with the `ecdsa` crate.

This naming scheme follows the philosophy that in a digital signature
scheme, it's clearer to name keys after their roles.

DSA admittedly benefits less than other schemes where there are other
potential algorithms that can be implemented using the same core
mathematics which share the same key representations.
This commit is contained in:
Tony Arcieri
2022-05-16 16:37:32 -06:00
committed by GitHub
parent a93a0730f9
commit ba86f16292
12 changed files with 136 additions and 138 deletions
+7 -7
View File
@@ -1,21 +1,21 @@
use dsa::{consts::DSA_2048_256, Components, PrivateKey};
use dsa::{consts::DSA_2048_256, Components, SigningKey};
use pkcs8::{EncodePrivateKey, EncodePublicKey, LineEnding};
use std::{fs::File, io::Write};
fn main() {
let mut rng = rand::thread_rng();
let components = Components::generate(&mut rng, DSA_2048_256);
let private_key = PrivateKey::generate(&mut rng, components);
let public_key = private_key.public_key();
let signing_key = SigningKey::generate(&mut rng, components);
let verifying_key = signing_key.verifying_key();
let private_key_bytes = private_key.to_pkcs8_pem(LineEnding::LF).unwrap();
let public_key_bytes = public_key.to_public_key_pem(LineEnding::LF).unwrap();
let signing_key_bytes = signing_key.to_pkcs8_pem(LineEnding::LF).unwrap();
let verifying_key_bytes = verifying_key.to_public_key_pem(LineEnding::LF).unwrap();
let mut file = File::create("public.pem").unwrap();
file.write_all(public_key_bytes.as_bytes()).unwrap();
file.write_all(verifying_key_bytes.as_bytes()).unwrap();
file.flush().unwrap();
let mut file = File::create("private.pem").unwrap();
file.write_all(private_key_bytes.as_bytes()).unwrap();
file.write_all(signing_key_bytes.as_bytes()).unwrap();
file.flush().unwrap();
}
+3 -3
View File
@@ -1,8 +1,8 @@
use dsa::{consts::DSA_2048_256, Components, PrivateKey};
use dsa::{consts::DSA_2048_256, Components, SigningKey};
fn main() {
let mut rng = rand::thread_rng();
let components = Components::generate(&mut rng, DSA_2048_256);
let private_key = PrivateKey::generate(&mut rng, components);
let _public_key = private_key.public_key();
let signing_key = SigningKey::generate(&mut rng, components);
let _verifying_key = signing_key.verifying_key();
}
+8 -8
View File
@@ -1,5 +1,5 @@
use digest::Digest;
use dsa::{consts::DSA_2048_256, Components, PrivateKey};
use dsa::{consts::DSA_2048_256, Components, SigningKey};
use pkcs8::{EncodePrivateKey, EncodePublicKey, LineEnding};
use sha1::Sha1;
use signature::{RandomizedDigestSigner, Signature};
@@ -8,17 +8,17 @@ use std::{fs::File, io::Write};
fn main() {
let mut rng = rand::thread_rng();
let components = Components::generate(&mut rng, DSA_2048_256);
let private_key = PrivateKey::generate(&mut rng, components);
let public_key = private_key.public_key();
let signing_key = SigningKey::generate(&mut rng, components);
let verifying_key = signing_key.verifying_key();
let signature = private_key
let signature = signing_key
.sign_digest_with_rng(rand::thread_rng(), Sha1::new().chain_update(b"hello world"));
let private_key_bytes = private_key.to_pkcs8_pem(LineEnding::LF).unwrap();
let public_key_bytes = public_key.to_public_key_pem(LineEnding::LF).unwrap();
let signing_key_bytes = signing_key.to_pkcs8_pem(LineEnding::LF).unwrap();
let verifying_key_bytes = verifying_key.to_public_key_pem(LineEnding::LF).unwrap();
let mut file = File::create("public.pem").unwrap();
file.write_all(public_key_bytes.as_bytes()).unwrap();
file.write_all(verifying_key_bytes.as_bytes()).unwrap();
file.flush().unwrap();
let mut file = File::create("signature.der").unwrap();
@@ -26,6 +26,6 @@ fn main() {
file.flush().unwrap();
let mut file = File::create("private.pem").unwrap();
file.write_all(private_key_bytes.as_bytes()).unwrap();
file.write_all(signing_key_bytes.as_bytes()).unwrap();
file.flush().unwrap();
}
+4 -4
View File
@@ -2,20 +2,20 @@
//! Generate a DSA keypair
//!
use crate::{generate::components, Components, PrivateKey, PublicKey};
use crate::{generate::components, Components, SigningKey, VerifyingKey};
use num_bigint::{BigUint, RandBigInt};
use num_traits::One;
use rand::{CryptoRng, RngCore};
/// Generate a new keypair
#[inline]
pub fn keypair<R>(rng: &mut R, components: Components) -> PrivateKey
pub fn keypair<R>(rng: &mut R, components: Components) -> SigningKey
where
R: CryptoRng + RngCore + ?Sized,
{
let x = rng.gen_biguint_range(&BigUint::one(), components.q());
let y = components::public(&components, &x);
let public_key = PublicKey::from_components(components, y);
PrivateKey::from_components(public_key, x)
let verifying_key = VerifyingKey::from_components(components, y);
SigningKey::from_components(verifying_key, x)
}
+4 -4
View File
@@ -2,7 +2,7 @@
//! Generate a per-message secret number
//!
use crate::{Components, PrivateKey};
use crate::{Components, SigningKey};
use alloc::{vec, vec::Vec};
use core::cmp::min;
use digest::{
@@ -42,7 +42,7 @@ fn reduce_hash(q: &BigUint, hash: &[u8]) -> Vec<u8> {
///
/// Secret number k and its modular multiplicative inverse with q
#[inline]
pub fn secret_number_rfc6979<D>(private_key: &PrivateKey, hash: &[u8]) -> (BigUint, BigUint)
pub fn secret_number_rfc6979<D>(signing_key: &SigningKey, hash: &[u8]) -> (BigUint, BigUint)
where
D: CoreProxy + FixedOutput,
D::Core: BlockSizeUser
@@ -55,11 +55,11 @@ where
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
{
let q = private_key.public_key().components().q();
let q = signing_key.verifying_key().components().q();
let k_size = q.bits() / 8;
let hash = reduce_hash(q, hash);
let mut x_bytes = private_key.x().to_bytes_be();
let mut x_bytes = signing_key.x().to_bytes_be();
let mut hmac = HmacDrbg::<D>::new(&x_bytes, &hash, &[]);
x_bytes.zeroize();
+11 -12
View File
@@ -11,17 +11,17 @@
//! Generate a DSA keypair
//!
//! ```
//! # use dsa::{consts::DSA_2048_256, Components, PrivateKey};
//! # use dsa::{consts::DSA_2048_256, Components, SigningKey};
//! let mut csprng = rand::thread_rng();
//! let components = Components::generate(&mut csprng, DSA_2048_256);
//! let private_key = PrivateKey::generate(&mut csprng, components);
//! let public_key = private_key.public_key();
//! let signing_key = SigningKey::generate(&mut csprng, components);
//! let verifying_key = signing_key.verifying_key();
//! ```
//!
//! Create keypair from existing components
//!
//! ```
//! # use dsa::{Components, PrivateKey, PublicKey};
//! # use dsa::{Components, SigningKey, VerifyingKey};
//! # use num_bigint::BigUint;
//! # use num_traits::One;
//! # let read_common_parameters = || (BigUint::one(), BigUint::one(), BigUint::one());
@@ -31,10 +31,10 @@
//! let components = Components::from_components(p, q, g);
//!
//! let x = read_public_component();
//! let public_key = PublicKey::from_components(components, x);
//! let verifying_key = VerifyingKey::from_components(components, x);
//!
//! let y = read_private_component();
//! let private_key = PrivateKey::from_components(public_key, y);
//! let signing_key = SigningKey::from_components(verifying_key, y);
//! ```
//!
@@ -43,10 +43,9 @@ extern crate alloc;
/// DSA object identifier as defined by RFC-3279, section 2.3.2
const DSA_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10040.4.1");
pub use self::components::Components;
pub use self::private_key::PrivateKey;
pub use self::public_key::PublicKey;
pub use self::sig::Signature;
pub use crate::{
components::Components, sig::Signature, signing_key::SigningKey, verifying_key::VerifyingKey,
};
pub use pkcs8;
pub use signature;
@@ -58,9 +57,9 @@ use pkcs8::spki::ObjectIdentifier;
mod components;
mod generate;
mod private_key;
mod public_key;
mod sig;
mod signing_key;
mod verifying_key;
/// Returns a `BigUint` with the value 2
#[inline]
@@ -2,7 +2,7 @@
//! Module containing the definition of the private key container
//!
use crate::{sig::Signature, Components, PublicKey, DSA_OID};
use crate::{sig::Signature, Components, VerifyingKey, DSA_OID};
use core::cmp::min;
use digest::{
block_buffer::Eager,
@@ -21,29 +21,29 @@ use rand::{CryptoRng, RngCore};
use signature::{DigestSigner, RandomizedDigestSigner};
use zeroize::Zeroizing;
/// DSA private key
/// DSA private key.
///
/// The [`(try_)sign_digest_with_rng`](::signature::RandomizedDigestSigner) API uses regular non-deterministic signatures,
/// while the [`(try_)sign_digest`](::signature::DigestSigner) API uses deterministic signatures as described in RFC 6979
#[derive(Clone, PartialEq)]
#[must_use]
pub struct PrivateKey {
pub struct SigningKey {
/// Public key
public_key: PublicKey,
verifying_key: VerifyingKey,
/// Private component x
x: Zeroizing<BigUint>,
}
opaque_debug::implement!(PrivateKey);
opaque_debug::implement!(SigningKey);
impl PrivateKey {
impl SigningKey {
/// Construct a new private key from the public key and private component
///
/// These values are not getting verified for validity
pub fn from_components(public_key: PublicKey, x: BigUint) -> Self {
pub fn from_components(verifying_key: VerifyingKey, x: BigUint) -> Self {
Self {
public_key,
verifying_key,
x: Zeroizing::new(x),
}
}
@@ -53,13 +53,13 @@ impl PrivateKey {
pub fn generate<R: CryptoRng + RngCore + ?Sized>(
rng: &mut R,
components: Components,
) -> PrivateKey {
) -> SigningKey {
crate::generate::keypair(rng, components)
}
/// DSA public key
pub const fn public_key(&self) -> &PublicKey {
&self.public_key
pub const fn verifying_key(&self) -> &VerifyingKey {
&self.verifying_key
}
/// DSA private component
@@ -73,11 +73,11 @@ impl PrivateKey {
/// Check whether the private key is valid
#[must_use]
pub fn is_valid(&self) -> bool {
if !self.public_key().is_valid() {
if !self.verifying_key().is_valid() {
return false;
}
*self.x() >= BigUint::one() && self.x() < self.public_key().components().q()
*self.x() >= BigUint::one() && self.x() < self.verifying_key().components().q()
}
/// Sign some pre-hashed data
@@ -87,7 +87,7 @@ impl PrivateKey {
return None;
}
let components = self.public_key().components();
let components = self.verifying_key().components();
let (p, q, g) = (components.p(), components.q(), components.g());
let x = self.x();
@@ -105,7 +105,7 @@ impl PrivateKey {
}
}
impl<D> DigestSigner<D, Signature> for PrivateKey
impl<D> DigestSigner<D, Signature> for SigningKey
where
D: Digest + CoreProxy + FixedOutput,
D::Core: BlockSizeUser
@@ -127,7 +127,7 @@ where
}
}
impl<D> RandomizedDigestSigner<D, Signature> for PrivateKey
impl<D> RandomizedDigestSigner<D, Signature> for SigningKey
where
D: Digest,
{
@@ -136,7 +136,7 @@ where
mut rng: impl CryptoRng + RngCore,
digest: D,
) -> Result<Signature, signature::Error> {
let ks = crate::generate::secret_number(&mut rng, self.public_key().components())
let ks = crate::generate::secret_number(&mut rng, self.verifying_key().components())
.ok_or_else(signature::Error::new)?;
let hash = digest.finalize();
@@ -145,9 +145,9 @@ where
}
}
impl EncodePrivateKey for PrivateKey {
impl EncodePrivateKey for SigningKey {
fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument> {
let parameters = self.public_key().components().to_vec()?;
let parameters = self.verifying_key().components().to_vec()?;
let parameters = AnyRef::from_der(&parameters)?;
let algorithm = AlgorithmIdentifier {
oid: DSA_OID,
@@ -156,14 +156,14 @@ impl EncodePrivateKey for PrivateKey {
let x_bytes = self.x.to_bytes_be();
let x = UIntRef::new(&x_bytes)?;
let private_key = x.to_vec()?;
let signing_key = x.to_vec()?;
let private_key_info = PrivateKeyInfo::new(algorithm, &private_key);
private_key_info.try_into()
let signing_key_info = PrivateKeyInfo::new(algorithm, &signing_key);
signing_key_info.try_into()
}
}
impl<'a> TryFrom<PrivateKeyInfo<'a>> for PrivateKey {
impl<'a> TryFrom<PrivateKeyInfo<'a>> for SigningKey {
type Error = pkcs8::Error;
fn try_from(value: PrivateKeyInfo<'a>) -> Result<Self, Self::Error> {
@@ -186,15 +186,15 @@ impl<'a> TryFrom<PrivateKeyInfo<'a>> for PrivateKey {
crate::generate::public_component(&components, &x)
};
let public_key = PublicKey::from_components(components, y);
let private_key = PrivateKey::from_components(public_key, x);
let verifying_key = VerifyingKey::from_components(components, y);
let signing_key = SigningKey::from_components(verifying_key, x);
if !private_key.is_valid() {
if !signing_key.is_valid() {
return Err(pkcs8::Error::KeyMalformed);
}
Ok(private_key)
Ok(signing_key)
}
}
impl DecodePrivateKey for PrivateKey {}
impl DecodePrivateKey for SigningKey {}
@@ -13,10 +13,10 @@ use pkcs8::{
};
use signature::DigestVerifier;
/// DSA public key
/// DSA public key.
#[derive(Clone, PartialEq, PartialOrd)]
#[must_use]
pub struct PublicKey {
pub struct VerifyingKey {
/// common components
components: Components,
@@ -24,9 +24,9 @@ pub struct PublicKey {
y: BigUint,
}
opaque_debug::implement!(PublicKey);
opaque_debug::implement!(VerifyingKey);
impl PublicKey {
impl VerifyingKey {
/// Construct a new public key from the common components and the public component
///
/// These values are not getting verified for validity
@@ -85,7 +85,7 @@ impl PublicKey {
}
}
impl<D> DigestVerifier<D, Signature> for PublicKey
impl<D> DigestVerifier<D, Signature> for VerifyingKey
where
D: Digest,
{
@@ -104,7 +104,7 @@ where
}
}
impl EncodePublicKey for PublicKey {
impl EncodePublicKey for VerifyingKey {
fn to_public_key_der(&self) -> spki::Result<spki::Document> {
let parameters = self.components.to_vec()?;
let parameters = AnyRef::from_der(&parameters)?;
@@ -117,16 +117,15 @@ impl EncodePublicKey for PublicKey {
let y = UIntRef::new(&y_bytes)?;
let public_key = y.to_vec()?;
let public_key_info = SubjectPublicKeyInfo {
SubjectPublicKeyInfo {
algorithm,
subject_public_key: &public_key,
};
public_key_info.try_into()
}
.try_into()
}
}
impl<'a> TryFrom<SubjectPublicKeyInfo<'a>> for PublicKey {
impl<'a> TryFrom<SubjectPublicKeyInfo<'a>> for VerifyingKey {
type Error = spki::Error;
fn try_from(value: SubjectPublicKeyInfo<'a>) -> Result<Self, Self::Error> {
@@ -142,4 +141,4 @@ impl<'a> TryFrom<SubjectPublicKeyInfo<'a>> for PublicKey {
}
}
impl DecodePublicKey for PublicKey {}
impl DecodePublicKey for VerifyingKey {}
+11 -11
View File
@@ -5,7 +5,7 @@ use digest::{
typenum::{IsLess, Le, NonZero},
Digest, FixedOutput, HashMarker, OutputSizeUser,
};
use dsa::{Components, PrivateKey, PublicKey, Signature};
use dsa::{Components, Signature, SigningKey, VerifyingKey};
use num_bigint::BigUint;
use num_traits::Num;
use sha1::Sha1;
@@ -15,7 +15,7 @@ use signature::DigestSigner;
const MESSAGE: &[u8] = b"sample";
const MESSAGE_2: &[u8] = b"test";
fn dsa_1024_private_key() -> PrivateKey {
fn dsa_1024_signing_key() -> SigningKey {
let p = BigUint::from_str_radix(
"86F5CA03DCFEB225063FF830A0C769B9DD9D6153AD91D7CE27F787C43278B447\
E6533B86B18BED6E8A48B784A14C252C5BE0DBF60B86D6385BD2F12FB763ED88\
@@ -45,12 +45,12 @@ fn dsa_1024_private_key() -> PrivateKey {
.unwrap();
let components = Components::from_components(p, q, g);
let public_key = PublicKey::from_components(components, y);
let verifying_key = VerifyingKey::from_components(components, y);
PrivateKey::from_components(public_key, x)
SigningKey::from_components(verifying_key, x)
}
fn dsa_2048_private_key() -> PrivateKey {
fn dsa_2048_signing_key() -> SigningKey {
let p = BigUint::from_str_radix(
"9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48\
C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44F\
@@ -100,13 +100,13 @@ fn dsa_2048_private_key() -> PrivateKey {
.unwrap();
let components = Components::from_components(p, q, g);
let public_key = PublicKey::from_components(components, y);
let verifying_key = VerifyingKey::from_components(components, y);
PrivateKey::from_components(public_key, x)
SigningKey::from_components(verifying_key, x)
}
/// Generate a signature given the unhashed message and a private key
fn generate_signature<D>(private_key: PrivateKey, data: &[u8]) -> Signature
fn generate_signature<D>(signing_key: SigningKey, data: &[u8]) -> Signature
where
D: Digest + CoreProxy + FixedOutput,
D::Core: BlockSizeUser
@@ -119,7 +119,7 @@ where
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
{
private_key.sign_digest(<D as Digest>::new().chain_update(data))
signing_key.sign_digest(<D as Digest>::new().chain_update(data))
}
/// Generate a signature using the 1024-bit DSA key
@@ -136,7 +136,7 @@ where
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
{
generate_signature::<D>(dsa_1024_private_key(), data)
generate_signature::<D>(dsa_1024_signing_key(), data)
}
/// Generate a signature using the 2048-bit DSA key
@@ -153,7 +153,7 @@ where
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
{
generate_signature::<D>(dsa_2048_private_key(), data)
generate_signature::<D>(dsa_2048_signing_key(), data)
}
/// Create a signature container from the two components in their textual hexadecimal form
+22 -22
View File
@@ -3,7 +3,7 @@
#![allow(deprecated)]
use digest::Digest;
use dsa::{consts::DSA_1024_160, Components, PrivateKey};
use dsa::{consts::DSA_1024_160, Components, SigningKey};
use num_bigint::BigUint;
use num_traits::Zero;
use pkcs8::{DecodePrivateKey, EncodePrivateKey, LineEnding};
@@ -12,61 +12,61 @@ use signature::{DigestVerifier, RandomizedDigestSigner};
const OPENSSL_PEM_PRIVATE_KEY: &str = include_str!("pems/private.pem");
fn generate_keypair() -> PrivateKey {
fn generate_keypair() -> SigningKey {
let mut rng = rand::thread_rng();
let components = Components::generate(&mut rng, DSA_1024_160);
PrivateKey::generate(&mut rng, components)
SigningKey::generate(&mut rng, components)
}
#[test]
fn decode_encode_openssl_private_key() {
let private_key = PrivateKey::from_pkcs8_pem(OPENSSL_PEM_PRIVATE_KEY)
fn decode_encode_openssl_signing_key() {
let signing_key = SigningKey::from_pkcs8_pem(OPENSSL_PEM_PRIVATE_KEY)
.expect("Failed to decode PEM encoded OpenSSL key");
assert!(private_key.is_valid());
assert!(signing_key.is_valid());
let reencoded_private_key = private_key
let reencoded_signing_key = signing_key
.to_pkcs8_pem(LineEnding::LF)
.expect("Failed to encode private key into PEM representation");
assert_eq!(*reencoded_private_key, OPENSSL_PEM_PRIVATE_KEY);
assert_eq!(*reencoded_signing_key, OPENSSL_PEM_PRIVATE_KEY);
}
#[test]
fn encode_decode_private_key() {
let private_key = generate_keypair();
let encoded_private_key = private_key.to_pkcs8_pem(LineEnding::LF).unwrap();
let decoded_private_key = PrivateKey::from_pkcs8_pem(&encoded_private_key).unwrap();
fn encode_decode_signing_key() {
let signing_key = generate_keypair();
let encoded_signing_key = signing_key.to_pkcs8_pem(LineEnding::LF).unwrap();
let decoded_signing_key = SigningKey::from_pkcs8_pem(&encoded_signing_key).unwrap();
assert_eq!(private_key, decoded_private_key);
assert_eq!(signing_key, decoded_signing_key);
}
#[test]
fn sign_and_verify() {
const DATA: &[u8] = b"SIGN AND VERIFY THOSE BYTES";
let private_key = generate_keypair();
let public_key = private_key.public_key();
let signing_key = generate_keypair();
let verifying_key = signing_key.verifying_key();
let signature =
private_key.sign_digest_with_rng(rand::thread_rng(), Sha1::new().chain_update(DATA));
signing_key.sign_digest_with_rng(rand::thread_rng(), Sha1::new().chain_update(DATA));
assert!(public_key
assert!(verifying_key
.verify_digest(Sha1::new().chain_update(DATA), &signature)
.is_ok());
}
#[test]
fn verify_validity() {
let private_key = generate_keypair();
let components = private_key.public_key().components();
let signing_key = generate_keypair();
let components = signing_key.verifying_key().components();
assert!(
BigUint::zero() < *private_key.x() && private_key.x() < components.q(),
BigUint::zero() < *signing_key.x() && signing_key.x() < components.q(),
"Requirement 0<x<q not met"
);
assert_eq!(
*private_key.public_key().y(),
components.g().modpow(private_key.x(), components.p()),
*signing_key.verifying_key().y(),
components.g().modpow(signing_key.x(), components.p()),
"Requirement y=(g^x)%p not met"
);
}
+19 -19
View File
@@ -2,49 +2,49 @@
// But we want to use those small key sizes for fast tests
#![allow(deprecated)]
use dsa::{consts::DSA_1024_160, Components, PrivateKey, PublicKey};
use dsa::{consts::DSA_1024_160, Components, SigningKey, VerifyingKey};
use num_bigint::BigUint;
use num_traits::One;
use pkcs8::{DecodePublicKey, EncodePublicKey, LineEnding};
const OPENSSL_PEM_PUBLIC_KEY: &str = include_str!("pems/public.pem");
fn generate_public_key() -> PublicKey {
fn generate_verifying_key() -> VerifyingKey {
let mut rng = rand::thread_rng();
let components = Components::generate(&mut rng, DSA_1024_160);
let private_key = PrivateKey::generate(&mut rng, components);
let signing_key = SigningKey::generate(&mut rng, components);
private_key.public_key().clone()
signing_key.verifying_key().clone()
}
#[test]
fn decode_encode_openssl_public_key() {
let public_key = PublicKey::from_public_key_pem(OPENSSL_PEM_PUBLIC_KEY)
fn decode_encode_openssl_verifying_key() {
let verifying_key = VerifyingKey::from_public_key_pem(OPENSSL_PEM_PUBLIC_KEY)
.expect("Failed to decode PEM encoded OpenSSL public key");
assert!(public_key.is_valid());
assert!(verifying_key.is_valid());
let reencoded_public_key = public_key
let reencoded_verifying_key = verifying_key
.to_public_key_pem(LineEnding::LF)
.expect("Failed to encode public key into PEM representation");
assert_eq!(reencoded_public_key, OPENSSL_PEM_PUBLIC_KEY);
assert_eq!(reencoded_verifying_key, OPENSSL_PEM_PUBLIC_KEY);
}
#[test]
fn encode_decode_public_key() {
let public_key = generate_public_key();
let encoded_public_key = public_key.to_public_key_pem(LineEnding::LF).unwrap();
let decoded_public_key = PublicKey::from_public_key_pem(&encoded_public_key).unwrap();
fn encode_decode_verifying_key() {
let verifying_key = generate_verifying_key();
let encoded_verifying_key = verifying_key.to_public_key_pem(LineEnding::LF).unwrap();
let decoded_verifying_key = VerifyingKey::from_public_key_pem(&encoded_verifying_key).unwrap();
assert_eq!(public_key, decoded_public_key);
assert_eq!(verifying_key, decoded_verifying_key);
}
#[test]
fn validate_public_key() {
let public_key = generate_public_key();
let p = public_key.components().p();
let q = public_key.components().q();
fn validate_verifying_key() {
let verifying_key = generate_verifying_key();
let p = verifying_key.components().p();
let q = verifying_key.components().q();
// Taken from the parameter validation from bouncy castle
assert_eq!(public_key.y().modpow(q, p), BigUint::one());
assert_eq!(verifying_key.y().modpow(q, p), BigUint::one());
}
+8 -8
View File
@@ -1,7 +1,7 @@
#![allow(deprecated)]
use digest::Digest;
use dsa::{consts::DSA_1024_160, Components, PrivateKey, Signature};
use dsa::{consts::DSA_1024_160, Components, Signature, SigningKey};
use pkcs8::der::{Decode, Encode};
use rand::{CryptoRng, RngCore, SeedableRng};
use rand_chacha::ChaCha8Rng;
@@ -38,10 +38,10 @@ fn seeded_csprng() -> impl CryptoRng + RngCore {
}
/// Generate a DSA keypair using a seeded CSPRNG
fn generate_deterministic_keypair() -> PrivateKey {
fn generate_deterministic_keypair() -> SigningKey {
let mut rng = seeded_csprng();
let components = Components::generate(&mut rng, DSA_1024_160);
PrivateKey::generate(&mut rng, components)
SigningKey::generate(&mut rng, components)
}
#[test]
@@ -65,9 +65,9 @@ fn decode_encode_signature() {
#[test]
fn sign_message() {
let private_key = generate_deterministic_keypair();
let signing_key = generate_deterministic_keypair();
let generated_signature =
private_key.sign_digest_with_rng(seeded_csprng(), Sha256::new().chain_update(MESSAGE));
signing_key.sign_digest_with_rng(seeded_csprng(), Sha256::new().chain_update(MESSAGE));
let expected_signature =
Signature::from_der(MESSAGE_SIGNATURE_CRATE_ASN1).expect("Failed to decode signature");
@@ -77,13 +77,13 @@ fn sign_message() {
#[test]
fn verify_signature() {
let private_key = generate_deterministic_keypair();
let public_key = private_key.public_key();
let signing_key = generate_deterministic_keypair();
let verifying_key = signing_key.verifying_key();
let signature = Signature::from_der(MESSAGE_SIGNATURE_OPENSSL_ASN1)
.expect("Failed to parse ASN.1 representation of the test signature");
assert!(public_key
assert!(verifying_key
.verify_digest(Sha256::new().chain_update(MESSAGE), &signature)
.is_ok());
}