diff --git a/privatekey/privatekey.go b/privatekey/privatekey.go index 81caed3878e..39a248a462d 100644 --- a/privatekey/privatekey.go +++ b/privatekey/privatekey.go @@ -59,7 +59,7 @@ func verifyECDSA(privKey *ecdsa.PrivateKey, pubKey *ecdsa.PublicKey, msgHash has // Load decodes and parses a private key from the provided file path and returns // the private key as crypto.Signer. keyPath is expected to be a PEM formatted -// RSA or ECDSA private key in a PKCS #1, PKCS# 8, or SEC 1 container. The +// RSA, ECDSA, or ML-DSA private key in a PKCS #1, PKCS# 8, or SEC 1 container. The // embedded PublicKey of the provided private key will be verified as an actual // match for the private key and returned as a crypto.PublicKey. This function // is only intended for use in administrative tooling and tests. diff --git a/privatekey/verify_go127.go b/privatekey/verify_go127.go index 557ea4052d7..b31b7147d6a 100644 --- a/privatekey/verify_go127.go +++ b/privatekey/verify_go127.go @@ -10,6 +10,7 @@ import ( "errors" "fmt" "hash" + "io" ) // verify ensures that the embedded PublicKey of the provided privateKey is @@ -40,6 +41,28 @@ func verify(privateKey crypto.Signer) (crypto.Signer, crypto.PublicKey, error) { } } +// deterministicSigner is a crypto.Signer over an ML-DSA private key that signs +// with SignDeterministic as opposed to the default hedged Sign method. +type deterministicSigner struct { + key *mldsa.PrivateKey +} + +// NewDeterministicSigner returns a crypto.Signer over an ML-DSA private key +// that signs with SignDeterministic. +func NewDeterministicSigner(key *mldsa.PrivateKey) crypto.Signer { + return deterministicSigner{key: key} +} + +var _ crypto.Signer = deterministicSigner{} + +func (s deterministicSigner) Public() crypto.PublicKey { + return s.key.PublicKey() +} + +func (s deterministicSigner) Sign(_ io.Reader, message []byte, _ crypto.SignerOpts) ([]byte, error) { + return s.key.SignDeterministic(message, nil) +} + // verifyMLDSA verifies ML-DSA private keys. func verifyMLDSA(privKey *mldsa.PrivateKey, pubKey *mldsa.PublicKey, msgHash hash.Hash) (crypto.Signer, crypto.PublicKey, error) { sig, err := privKey.Sign(nil, msgHash.Sum(nil), nil) @@ -51,5 +74,5 @@ func verifyMLDSA(privKey *mldsa.PrivateKey, pubKey *mldsa.PublicKey, msgHash has if err != nil { return nil, nil, fmt.Errorf("the provided ML-DSA private key failed signature verification: %s", err) } - return privKey, privKey.Public(), nil + return NewDeterministicSigner(privKey), privKey.Public(), nil }