mirror of
https://github.com/RustCrypto/signatures
synced 2026-06-21 13:45:42 +00:00
ml-dsa: implement initial pkcs8/spki traits (#891)
This commit is contained in:
Generated
+2
@@ -683,11 +683,13 @@ checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||
name = "ml-dsa"
|
||||
version = "0.1.0-pre.0"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"criterion",
|
||||
"hex",
|
||||
"hex-literal",
|
||||
"hybrid-array",
|
||||
"num-traits",
|
||||
"pkcs8",
|
||||
"rand",
|
||||
"rand_core",
|
||||
"serde",
|
||||
|
||||
+7
-1
@@ -15,9 +15,11 @@ categories = ["cryptography"]
|
||||
keywords = ["crypto", "signature"]
|
||||
|
||||
[features]
|
||||
default = ["rand_core"]
|
||||
default = ["rand_core", "alloc", "pkcs8"]
|
||||
zeroize = ["dep:zeroize", "hybrid-array/zeroize"]
|
||||
rand_core = ["dep:rand_core", "signature/rand_core"]
|
||||
alloc = ["pkcs8?/alloc"]
|
||||
pkcs8 = ["dep:const-oid", "dep:pkcs8"]
|
||||
|
||||
[dependencies]
|
||||
hybrid-array = { version = "0.2.3", features = ["extra-sizes"] }
|
||||
@@ -27,10 +29,14 @@ sha3 = "0.10.8"
|
||||
signature = "2.3.0-pre.4"
|
||||
zeroize = { version = "1.8.1", optional = true, default-features = false }
|
||||
|
||||
const-oid = { version = "0.10.0-rc.1", features = ["db"], optional = true }
|
||||
pkcs8 = { version = "=0.11.0-rc.1", default-features = false, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.5.1"
|
||||
hex = { version = "0.4.3", features = ["serde"] }
|
||||
hex-literal = "0.4.1"
|
||||
pkcs8 = { version = "=0.11.0-rc.1", features = ["pem"] }
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.215", features = ["derive"] }
|
||||
serde_json = "1.0.132"
|
||||
|
||||
+191
-1
@@ -56,6 +56,26 @@ use rand_core::CryptoRngCore;
|
||||
#[cfg(feature = "zeroize")]
|
||||
use zeroize::{Zeroize, ZeroizeOnDrop};
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
use {
|
||||
const_oid::db::fips204,
|
||||
pkcs8::{
|
||||
der::{self, AnyRef},
|
||||
spki::{
|
||||
self, AlgorithmIdentifier, AssociatedAlgorithmIdentifier, SignatureAlgorithmIdentifier,
|
||||
SubjectPublicKeyInfoRef,
|
||||
},
|
||||
AlgorithmIdentifierRef, PrivateKeyInfoRef,
|
||||
},
|
||||
};
|
||||
|
||||
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
|
||||
use pkcs8::{
|
||||
der::asn1::{BitString, BitStringRef},
|
||||
spki::{SignatureBitStringEncoding, SubjectPublicKeyInfo},
|
||||
EncodePublicKey,
|
||||
};
|
||||
|
||||
use crate::algebra::{AlgebraExt, Elem, NttMatrix, NttVector, Truncate, Vector};
|
||||
use crate::crypto::H;
|
||||
use crate::hint::Hint;
|
||||
@@ -124,6 +144,24 @@ impl<P: MlDsaParams> signature::SignatureEncoding for Signature<P> {
|
||||
type Repr = EncodedSignature<P>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl<P: MlDsaParams> SignatureBitStringEncoding for Signature<P> {
|
||||
fn to_bitstring(&self) -> der::Result<BitString> {
|
||||
BitString::new(0, self.encode().to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
impl<P> AssociatedAlgorithmIdentifier for Signature<P>
|
||||
where
|
||||
P: MlDsaParams,
|
||||
P: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>,
|
||||
{
|
||||
type Params = AnyRef<'static>;
|
||||
|
||||
const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = P::ALGORITHM_IDENTIFIER;
|
||||
}
|
||||
|
||||
// This method takes a slice of slices so that we can accommodate the varying calculations (direct
|
||||
// for test vectors, 0... for sign/sign_deterministic, 1... for the pre-hashed version) without
|
||||
// having to allocate memory for components.
|
||||
@@ -156,6 +194,46 @@ impl<P: MlDsaParams> signature::KeypairRef for KeyPair<P> {
|
||||
type VerifyingKey = VerifyingKey<P>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
impl<P> TryFrom<PrivateKeyInfoRef<'_>> for KeyPair<P>
|
||||
where
|
||||
P: MlDsaParams,
|
||||
P: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>,
|
||||
{
|
||||
type Error = pkcs8::Error;
|
||||
|
||||
fn try_from(private_key_info: pkcs8::PrivateKeyInfoRef<'_>) -> pkcs8::Result<Self> {
|
||||
match private_key_info.algorithm {
|
||||
alg if alg == P::ALGORITHM_IDENTIFIER => {}
|
||||
other => return Err(spki::Error::OidUnknown { oid: other.oid }.into()),
|
||||
};
|
||||
|
||||
let seed = Array::try_from(private_key_info.private_key.as_bytes())
|
||||
.map_err(|_| pkcs8::Error::KeyMalformed)?;
|
||||
Ok(P::key_gen_internal(&seed))
|
||||
}
|
||||
}
|
||||
|
||||
/// The `Signer` implementation for `KeyPair` uses the optional deterministic variant of ML-DSA, and
|
||||
/// only supports signing with an empty context string.
|
||||
impl<P: MlDsaParams> signature::Signer<Signature<P>> for KeyPair<P> {
|
||||
fn try_sign(&self, msg: &[u8]) -> Result<Signature<P>, Error> {
|
||||
self.signing_key.sign_deterministic(msg, &[])
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
impl<P> SignatureAlgorithmIdentifier for KeyPair<P>
|
||||
where
|
||||
P: MlDsaParams,
|
||||
P: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>,
|
||||
{
|
||||
type Params = AnyRef<'static>;
|
||||
|
||||
const SIGNATURE_ALGORITHM_IDENTIFIER: AlgorithmIdentifier<Self::Params> =
|
||||
Signature::<P>::ALGORITHM_IDENTIFIER;
|
||||
}
|
||||
|
||||
/// An ML-DSA signing key
|
||||
#[derive(Clone, PartialEq)]
|
||||
pub struct SigningKey<P: MlDsaParams> {
|
||||
@@ -384,8 +462,35 @@ impl<P: MlDsaParams> signature::RandomizedSigner<Signature<P>> for SigningKey<P>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
impl<P> SignatureAlgorithmIdentifier for SigningKey<P>
|
||||
where
|
||||
P: MlDsaParams,
|
||||
P: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>,
|
||||
{
|
||||
type Params = AnyRef<'static>;
|
||||
|
||||
const SIGNATURE_ALGORITHM_IDENTIFIER: AlgorithmIdentifier<Self::Params> =
|
||||
Signature::<P>::ALGORITHM_IDENTIFIER;
|
||||
}
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
impl<P> TryFrom<PrivateKeyInfoRef<'_>> for SigningKey<P>
|
||||
where
|
||||
P: MlDsaParams,
|
||||
P: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>,
|
||||
{
|
||||
type Error = pkcs8::Error;
|
||||
|
||||
fn try_from(private_key_info: pkcs8::PrivateKeyInfoRef<'_>) -> pkcs8::Result<Self> {
|
||||
let keypair = KeyPair::try_from(private_key_info)?;
|
||||
|
||||
Ok(keypair.signing_key)
|
||||
}
|
||||
}
|
||||
|
||||
/// An ML-DSA verification key
|
||||
#[derive(Clone, PartialEq)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct VerifyingKey<P: ParameterSet> {
|
||||
rho: B32,
|
||||
t1: Vector<P::K>,
|
||||
@@ -488,6 +593,61 @@ impl<P: MlDsaParams> signature::Verifier<Signature<P>> for VerifyingKey<P> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
impl<P> SignatureAlgorithmIdentifier for VerifyingKey<P>
|
||||
where
|
||||
P: MlDsaParams,
|
||||
P: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>,
|
||||
{
|
||||
type Params = AnyRef<'static>;
|
||||
|
||||
const SIGNATURE_ALGORITHM_IDENTIFIER: AlgorithmIdentifier<Self::Params> =
|
||||
Signature::<P>::ALGORITHM_IDENTIFIER;
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl<P> EncodePublicKey for VerifyingKey<P>
|
||||
where
|
||||
P: MlDsaParams,
|
||||
P: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>,
|
||||
{
|
||||
fn to_public_key_der(&self) -> spki::Result<der::Document> {
|
||||
let public_key = self.encode();
|
||||
let subject_public_key = BitStringRef::new(0, &public_key)?;
|
||||
|
||||
SubjectPublicKeyInfo {
|
||||
algorithm: P::ALGORITHM_IDENTIFIER,
|
||||
subject_public_key,
|
||||
}
|
||||
.try_into()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
impl<P> TryFrom<SubjectPublicKeyInfoRef<'_>> for VerifyingKey<P>
|
||||
where
|
||||
P: MlDsaParams,
|
||||
P: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>,
|
||||
{
|
||||
type Error = spki::Error;
|
||||
|
||||
fn try_from(spki: SubjectPublicKeyInfoRef<'_>) -> spki::Result<Self> {
|
||||
match spki.algorithm {
|
||||
alg if alg == P::ALGORITHM_IDENTIFIER => {}
|
||||
other => return Err(spki::Error::OidUnknown { oid: other.oid }),
|
||||
};
|
||||
|
||||
Ok(Self::decode(
|
||||
&EncodedVerifyingKey::<P>::try_from(
|
||||
spki.subject_public_key
|
||||
.as_bytes()
|
||||
.ok_or_else(|| der::Tag::BitString.value_error())?,
|
||||
)
|
||||
.map_err(|_| pkcs8::Error::KeyMalformed)?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// `MlDsa44` is the parameter set for security category 2.
|
||||
#[derive(Default, Clone, Debug, PartialEq)]
|
||||
pub struct MlDsa44;
|
||||
@@ -505,6 +665,16 @@ impl ParameterSet for MlDsa44 {
|
||||
const TAU: usize = 39;
|
||||
}
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
impl AssociatedAlgorithmIdentifier for MlDsa44 {
|
||||
type Params = AnyRef<'static>;
|
||||
|
||||
const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = AlgorithmIdentifierRef {
|
||||
oid: fips204::ID_ML_DSA_44,
|
||||
parameters: None,
|
||||
};
|
||||
}
|
||||
|
||||
/// `MlDsa65` is the parameter set for security category 3.
|
||||
#[derive(Default, Clone, Debug, PartialEq)]
|
||||
pub struct MlDsa65;
|
||||
@@ -522,6 +692,16 @@ impl ParameterSet for MlDsa65 {
|
||||
const TAU: usize = 49;
|
||||
}
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
impl AssociatedAlgorithmIdentifier for MlDsa65 {
|
||||
type Params = AnyRef<'static>;
|
||||
|
||||
const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = AlgorithmIdentifierRef {
|
||||
oid: fips204::ID_ML_DSA_65,
|
||||
parameters: None,
|
||||
};
|
||||
}
|
||||
|
||||
/// `MlKem87` is the parameter set for security category 5.
|
||||
#[derive(Default, Clone, Debug, PartialEq)]
|
||||
pub struct MlDsa87;
|
||||
@@ -539,6 +719,16 @@ impl ParameterSet for MlDsa87 {
|
||||
const TAU: usize = 60;
|
||||
}
|
||||
|
||||
#[cfg(feature = "pkcs8")]
|
||||
impl AssociatedAlgorithmIdentifier for MlDsa87 {
|
||||
type Params = AnyRef<'static>;
|
||||
|
||||
const ALGORITHM_IDENTIFIER: AlgorithmIdentifierRef<'static> = AlgorithmIdentifierRef {
|
||||
oid: fips204::ID_ML_DSA_87,
|
||||
parameters: None,
|
||||
};
|
||||
}
|
||||
|
||||
/// A parameter set that knows how to generate key pairs
|
||||
pub trait KeyGen: MlDsaParams {
|
||||
/// The type that is returned by key generation
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MDICAQAwCwYJYIZIAWUDBAMRBCAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRob
|
||||
HB0eHw==
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1,30 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIFMjALBglghkgBZQMEAxEDggUhANeytHJUquDbReeTDUqY0sl9jxOX0Xidr6Fw
|
||||
JLMW6b7JT8mUbULxm3mnQTu6oz5xSctC7VEVaTrAQfrLmIretf4OHYYxGEmVtZLD
|
||||
l9IpTi4U+QqkFLo4JomaxD9MzKy8JumoMrlRGNXLQzy++WYLABOOCBf2HnYsonTD
|
||||
atVU6yKqwRYuSrAay6HjjE79j4C2WzM9D3LlXf5xzpweu5iJ58VhBsD9c4A6Kuz+
|
||||
r97XqjyyztpU0SvYzTanjPl1lDtHq9JeiArEUuV0LtHo0agq+oblkMdYwVrk0oQN
|
||||
kryhpQkPQElll/yn2LlRPxob2m6VCqqY3kZ1B9Sk9aTwWZIWWCw1cvYu2okFqzWB
|
||||
ZwxKAnd6M+DKcpX9j0/20aCjp2g9ZfX19/xg2gI+gmxfkhRMAvfRuhB1mHVT6pNn
|
||||
/NdtmQt/qZzUWv24g21D5Fn1GH3wWEeXCaAepoNZNfpwRgmQzT3BukAbqUurHd5B
|
||||
rGerMxncrKBgSNTE7vJ+4TqcF9BTj0MPLWQtwkFWYN54h32NirxyUjl4wELkKF9D
|
||||
GYRsRBJiQpdoRMEOVWuiFbWnGeWdDGsqltOYWQcf3MLN51JKe+2uVOhbMY6FTo/i
|
||||
svPt+slxkSgnCq/R5QRMOk/a/Z/zH5B4S46ORZYUSg2vWGUR09mWK56pWvGXtOX8
|
||||
YPKx7RXeOlvvX4m9x52RBR2bKBbnT6VFMe/cHL501EiFf0drzVjyHAtlOzt2pOB2
|
||||
plWaMCcYVVzGP3SFmqurkl8COGHKjND3utsocfZ9VTJtdFETWtRfShumkRj7ssij
|
||||
DuyTku8/l3Bmya3VxxDMZHsVFNIX2VjHAXw+kP0gwE5nS5BIbpNwoxoAHTL0c5ee
|
||||
SQZ0nn5Hf6C3RQj4pfI3gxK4PCW9OIygsP/3R4uvQrcWZ+2qyXxGsSlkPlhuWwVa
|
||||
DCEZRtTzbmdb7Vhg+gQqMV2YJhZNapI3w1pfv0lUkKW9TfJIuVxKrneEtgVnMWas
|
||||
QkW1tLCCoJ6TI+YvIHjFt2eDRG3v1zatOjcC1JsImESQCmGDM5e8RBmzDXqXoLOH
|
||||
wZEUdMTUG1PjKpd6y28Op122W7OeWecB52lX3vby1EVZwxp3EitSBOO1whnxaIsU
|
||||
7QvAuAGz5ugtzUPpwOn0F0TNmBW9G8iCDYuxI/BPrNGxtoXdWisbjbvz7ZM2cPCV
|
||||
oYC08ZLQixC4+rvfzCskUY4y7qCl4MkEyoRHgAg/OwzS0Li2r2e8NVuUlAJdx7Cn
|
||||
j6gOOi2/61EyiFHWB4GY6Uk2Ua54fsAlH5Irow6fUd9iptcnhM890gU5MXbfoySl
|
||||
Er2Ulwo23TSlFKhnkfDrNvAUWwmrZGUbSgMTsplhGiocSIkWJ1mHaKMRQGC6RENI
|
||||
bfUVIqHOiLMJhcIW+ObtF43VZ7MEoNTK+6iCooNC8XqaomrljbYwCD0sNY/fVmw/
|
||||
XWKkKFZ7yeqM6VyqDzVHSwv6jzOaJQq0388gg76O77wQVeGP4VNw7ssmBWbYP/Br
|
||||
IRquxDyim1TM0A+IFaJGXvC0ZRXMfkHzEk8J7/9zkwmrWLKaFFmgC85QOOk4yWeP
|
||||
cusOTuX9quZtn4Vz/Jf8QrSVn0v4th14Qz6GsDNdbpGRxNi/SHs5BcEIz9asJLDO
|
||||
t9y3z1H4TQ7Wh7lerrHFM8BvDZcCPZKnCCWDe1m6bLfU5WsKh8IDhiro8xW6WSXo
|
||||
7e+meTaaIgJ2YVHxapZfn4Hs52zAcLVYaeTbl4TPBcgwsyQsgxI=
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -0,0 +1,4 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MDICAQAwCwYJYIZIAWUDBAMSBCAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRob
|
||||
HB0eHw==
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1,44 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
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
|
||||
HgLy6ERP
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -0,0 +1,4 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MDICAQAwCwYJYIZIAWUDBAMTBCAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRob
|
||||
HB0eHw==
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1,57 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
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
|
||||
5VvgYiIvi6kKl0BzMmsxISrs4KNKYA==
|
||||
-----END PUBLIC KEY-----
|
||||
@@ -0,0 +1 @@
|
||||
Examples found in this directory can be found in https://github.com/lamps-wg/dilithium-certificates/tree/main/examples
|
||||
@@ -0,0 +1,46 @@
|
||||
#![cfg(all(feature = "pkcs8", feature = "alloc"))]
|
||||
|
||||
use core::ops::Deref;
|
||||
use ml_dsa::{KeyPair, MlDsa44, MlDsa65, MlDsa87, MlDsaParams, SigningKey, VerifyingKey};
|
||||
use pkcs8::{
|
||||
der::{pem::LineEnding, AnyRef},
|
||||
spki::AssociatedAlgorithmIdentifier,
|
||||
DecodePrivateKey, DecodePublicKey, EncodePublicKey,
|
||||
};
|
||||
use signature::Keypair;
|
||||
|
||||
#[test]
|
||||
fn private_key_serialization() {
|
||||
fn test_roundtrip<P>(private_bytes: &str, public_bytes: &str)
|
||||
where
|
||||
P: MlDsaParams,
|
||||
P: AssociatedAlgorithmIdentifier<Params = AnyRef<'static>>,
|
||||
{
|
||||
let sk = SigningKey::<P>::from_pkcs8_pem(private_bytes).expect("parse private key");
|
||||
let kp = KeyPair::<P>::from_pkcs8_pem(private_bytes).expect("parse private key");
|
||||
assert!(sk == kp.signing_key);
|
||||
|
||||
let pk = VerifyingKey::<P>::from_public_key_pem(public_bytes).expect("parse public key");
|
||||
assert_eq!(
|
||||
pk.to_public_key_pem(LineEnding::LF)
|
||||
.expect("serialize public key")
|
||||
.deref(),
|
||||
public_bytes
|
||||
);
|
||||
|
||||
assert_eq!(kp.verifying_key(), pk);
|
||||
}
|
||||
|
||||
test_roundtrip::<MlDsa44>(
|
||||
include_str!("examples/ML-DSA-44.priv"),
|
||||
include_str!("examples/ML-DSA-44.pub"),
|
||||
);
|
||||
test_roundtrip::<MlDsa65>(
|
||||
include_str!("examples/ML-DSA-65.priv"),
|
||||
include_str!("examples/ML-DSA-65.pub"),
|
||||
);
|
||||
test_roundtrip::<MlDsa87>(
|
||||
include_str!("examples/ML-DSA-87.priv"),
|
||||
include_str!("examples/ML-DSA-87.pub"),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user