Skip to content

Commit 8a5f08c

Browse files
committed
feat(pqc): Update mlkem/mldsa to draft-ietf-openpgp-pqc-09
1 parent e9ff5ef commit 8a5f08c

23 files changed

+1139
-1139
lines changed

openpgp/clearsign/clearsign.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ func nameOfHash(h crypto.Hash) string {
527527

528528
func acceptableHashesToWrite(singingKey *packet.PublicKey) []crypto.Hash {
529529
switch singingKey.PubKeyAlgo {
530-
case packet.PubKeyAlgoEd448:
530+
case packet.PubKeyAlgoEd448, packet.PubKeyAlgoMldsa87Ed448:
531531
return []crypto.Hash{
532532
crypto.SHA512,
533533
crypto.SHA3_512,

openpgp/key_generation.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,8 @@ func newDecrypter(config *packet.Config) (decrypter interface{}, err error) {
392392
}
393393
fallthrough // When passing ML-DSA + EdDSA or ECDSA, we generate a ML-KEM + ECDH subkey
394394
case packet.PubKeyAlgoMlkem768X25519, packet.PubKeyAlgoMlkem1024X448:
395-
if !config.V6() {
396-
return nil, goerrors.New("openpgp: cannot create a non-v6 mlkem_x25519 key")
395+
if !config.V6() && pubKeyAlgo == packet.PubKeyAlgoMlkem1024X448 {
396+
return nil, goerrors.New("openpgp: cannot create a non-v6 mlkem1024_x448 key")
397397
}
398398

399399
c, err := packet.GetECDHCurveFromAlgID(pubKeyAlgo)

openpgp/mldsa_eddsa/mldsa_eddsa.go

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Package mldsa_eddsa implements hybrid ML-DSA + EdDSA encryption, suitable for OpenPGP, experimental.
2-
// It follows the specs https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-composite-signature-schemes
2+
// It follows the specs https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-composite-signature-schemes
33
package mldsa_eddsa
44

55
import (
@@ -9,6 +9,8 @@ import (
99
"github.com/ProtonMail/go-crypto/openpgp/errors"
1010
"github.com/ProtonMail/go-crypto/openpgp/internal/ecc"
1111
"github.com/cloudflare/circl/sign"
12+
"github.com/cloudflare/circl/sign/mldsa/mldsa65"
13+
"github.com/cloudflare/circl/sign/mldsa/mldsa87"
1214
)
1315

1416
const (
@@ -31,7 +33,7 @@ type PrivateKey struct {
3133
}
3234

3335
// GenerateKey generates a ML-DSA + EdDSA composite key as specified in
34-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-key-generation-procedure-2
36+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-key-generation-procedure-2
3537
func GenerateKey(rand io.Reader, algId uint8, c ecc.EdDSACurve, d sign.Scheme) (priv *PrivateKey, err error) {
3638
priv = new(PrivateKey)
3739

@@ -70,23 +72,35 @@ func (priv *PrivateKey) DeriveMlDsaKeys(seed []byte, overridePublicKey bool) (er
7072
}
7173

7274
// Sign generates a ML-DSA + EdDSA composite signature as specified in
73-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-signature-generation
74-
func Sign(priv *PrivateKey, message []byte) (dSig, ecSig []byte, err error) {
75+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-signature-generation
76+
func Sign(priv *PrivateKey, message []byte) (mldsaSig, ecSig []byte, err error) {
7577
ecSig, err = priv.PublicKey.Curve.Sign(priv.PublicKey.PublicPoint, priv.SecretEc, message)
7678
if err != nil {
7779
return nil, nil, err
7880
}
7981

80-
dSig = priv.PublicKey.Mldsa.Sign(priv.SecretMldsa, message, nil)
81-
if dSig == nil {
82-
return nil, nil, goerrors.New("mldsa_eddsa: unable to sign with ML-DSA")
82+
// The default signer interface does not use the hedged variant.
83+
// Thus, we need to use the low level api
84+
switch key := priv.SecretMldsa.(type) {
85+
case *mldsa65.PrivateKey:
86+
mldsaSig = make([]byte, mldsa65.SignatureSize)
87+
err = mldsa65.SignTo(key, message, nil, true, mldsaSig)
88+
case *mldsa87.PrivateKey:
89+
mldsaSig = make([]byte, mldsa87.SignatureSize)
90+
err = mldsa87.SignTo(key, message, nil, true, mldsaSig)
91+
default:
92+
err = goerrors.New("mldsa_eddsa: unsupported ML-DSA private key type")
8393
}
8494

85-
return dSig, ecSig, nil
95+
if err != nil {
96+
return nil, nil, err
97+
}
98+
99+
return mldsaSig, ecSig, nil
86100
}
87101

88102
// Verify verifies a ML-DSA + EdDSA composite signature as specified in
89-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-signature-verification
103+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-signature-verification
90104
func Verify(pub *PublicKey, message, dSig, ecSig []byte) bool {
91105
return pub.Curve.Verify(pub.PublicPoint, message, ecSig) && pub.Mldsa.Verify(pub.PublicMldsa, message, dSig, nil)
92106
}

openpgp/mlkem_ecdh/mlkem_ecdh.go

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Package mlkem_ecdh implements hybrid ML-KEM + ECDH encryption, suitable for OpenPGP, experimental.
2-
// It follows the spec https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-composite-kem-schemes
2+
// It follows the spec https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-composite-kem-schemes
33
package mlkem_ecdh
44

55
import (
@@ -19,7 +19,7 @@ import (
1919
const (
2020
maxSessionKeyLength = 64
2121
MlKemSeedLen = 64
22-
kdfContext = "OpenPGPCompositeKDFv1"
22+
domSep = "OpenPGPCompositeKDFv1"
2323
)
2424

2525
type PublicKey struct {
@@ -38,7 +38,7 @@ type PrivateKey struct {
3838
}
3939

4040
// GenerateKey implements ML-KEM + ECC key generation as specified in
41-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-key-generation-procedure
41+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-key-generation-procedure
4242
func GenerateKey(rand io.Reader, algId uint8, c ecc.ECDHCurve, k kem.Scheme) (priv *PrivateKey, err error) {
4343
priv = new(PrivateKey)
4444

@@ -77,7 +77,7 @@ func (priv *PrivateKey) DeriveMlKemKeys(seed []byte, overridePublicKey bool) (er
7777
}
7878

7979
// Encrypt implements ML-KEM + ECC encryption as specified in
80-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-encryption-procedure
80+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-encryption-procedure
8181
func Encrypt(rand io.Reader, pub *PublicKey, msg []byte) (kEphemeral, ecEphemeral, ciphertext []byte, err error) {
8282
if len(msg) > maxSessionKeyLength {
8383
return nil, nil, nil, goerrors.New("mlkem_ecdh: session key too long")
@@ -104,7 +104,7 @@ func Encrypt(rand io.Reader, pub *PublicKey, msg []byte) (kEphemeral, ecEphemera
104104
return nil, nil, nil, err
105105
}
106106

107-
keyEncryptionKey, err := buildKey(pub, ecSS, ecEphemeral, pub.PublicPoint, kSS, kEphemeral, pub.PublicMlkem)
107+
keyEncryptionKey, err := buildKey(pub, ecSS, ecEphemeral, pub.PublicPoint, kSS)
108108
if err != nil {
109109
return nil, nil, nil, err
110110
}
@@ -117,7 +117,7 @@ func Encrypt(rand io.Reader, pub *PublicKey, msg []byte) (kEphemeral, ecEphemera
117117
}
118118

119119
// Decrypt implements ML-KEM + ECC decryption as specified in
120-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-decryption-procedure
120+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-decryption-procedure
121121
func Decrypt(priv *PrivateKey, kEphemeral, ecEphemeral, ciphertext []byte) (msg []byte, err error) {
122122
// EC shared secret derivation
123123
ecSS, err := priv.PublicKey.Curve.Decaps(ecEphemeral, priv.SecretEc)
@@ -131,7 +131,7 @@ func Decrypt(priv *PrivateKey, kEphemeral, ecEphemeral, ciphertext []byte) (msg
131131
return nil, err
132132
}
133133

134-
kek, err := buildKey(&priv.PublicKey, ecSS, ecEphemeral, priv.PublicPoint, kSS, kEphemeral, priv.PublicMlkem)
134+
kek, err := buildKey(&priv.PublicKey, ecSS, ecEphemeral, priv.PublicPoint, kSS)
135135
if err != nil {
136136
return nil, err
137137
}
@@ -140,35 +140,27 @@ func Decrypt(priv *PrivateKey, kEphemeral, ecEphemeral, ciphertext []byte) (msg
140140
}
141141

142142
// buildKey implements the composite KDF from
143-
// https://github.com/openpgp-pqc/draft-openpgp-pqc/pull/161
144-
func buildKey(pub *PublicKey, eccSecretPoint, eccEphemeral, eccPublicKey, mlkemKeyShare, mlkemEphemeral []byte, mlkemPublicKey kem.PublicKey) ([]byte, error) {
143+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-key-combiner
144+
func buildKey(pub *PublicKey, eccSecretPoint, eccCipherText, eccPublicKey, mlkemKeyShare []byte) ([]byte, error) {
145145
/// Set the output `ecdhKeyShare` to `eccSecretPoint`
146146
eccKeyShare := eccSecretPoint
147147

148-
serializedMlkemPublicKey, err := mlkemPublicKey.MarshalBinary()
149-
if err != nil {
150-
return nil, err
151-
}
152-
153148
// mlkemKeyShare - the ML-KEM key share encoded as an octet string
154-
// mlkemEphemeral - the ML-KEM ciphertext encoded as an octet string
155-
// mlkemPublicKey - The ML-KEM public key of the recipient as an octet string
156149
// algId - the OpenPGP algorithm ID of the public-key encryption algorithm
157150
// eccKeyShare - the ECDH key share encoded as an octet string
158-
// eccEphemeral - the ECDH ciphertext encoded as an octet string
151+
// eccCipherText - the ECDH ciphertext encoded as an octet string
159152
// eccPublicKey - The ECDH public key of the recipient as an octet string
160153

161-
// SHA3-256(mlkemKeyShare || eccKeyShare || eccEphemeral || eccPublicKey ||
162-
// mlkemEphemeral || mlkemPublicKey || algId || "OpenPGPCompositeKDFv1")
154+
// SHA3-256(mlkemKeyShare || eccKeyShare || eccCipherText || eccPublicKey ||
155+
// algId || "OpenPGPCompositeKDFv1" || len("OpenPGPCompositeKDFv1"))
163156
h := sha3.New256()
164157
_, _ = h.Write(mlkemKeyShare)
165158
_, _ = h.Write(eccKeyShare)
166-
_, _ = h.Write(eccEphemeral)
159+
_, _ = h.Write(eccCipherText)
167160
_, _ = h.Write(eccPublicKey)
168-
_, _ = h.Write(mlkemEphemeral)
169-
_, _ = h.Write(serializedMlkemPublicKey)
170161
_, _ = h.Write([]byte{pub.AlgId})
171-
_, _ = h.Write([]byte(kdfContext))
162+
_, _ = h.Write([]byte(domSep))
163+
_, _ = h.Write([]byte{byte(len(domSep))})
172164
return h.Sum(nil), nil
173165
}
174166

openpgp/packet/packet.go

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ package packet // import "github.com/ProtonMail/go-crypto/openpgp/packet"
88

99
import (
1010
"bytes"
11-
"crypto"
1211
"crypto/cipher"
1312
"crypto/rsa"
1413
"io"
@@ -514,13 +513,13 @@ const (
514513
PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2
515514
PubKeyAlgoRSASignOnly PublicKeyAlgorithm = 3
516515

517-
// Experimental PQC KEM algorithms
518-
PubKeyAlgoMlkem768X25519 = 105
519-
PubKeyAlgoMlkem1024X448 = 106
516+
// PQC DSA algorithms
517+
PubKeyAlgoMldsa65Ed25519 = 30
518+
PubKeyAlgoMldsa87Ed448 = 31
520519

521-
// Experimental PQC DSA algorithms
522-
PubKeyAlgoMldsa65Ed25519 = 107
523-
PubKeyAlgoMldsa87Ed448 = 108
520+
// PQC KEM algorithms
521+
PubKeyAlgoMlkem768X25519 = 35
522+
PubKeyAlgoMlkem1024X448 = 36
524523
)
525524

526525
// CanEncrypt returns true if it's possible to encrypt a message to a public
@@ -545,18 +544,6 @@ func (pka PublicKeyAlgorithm) CanSign() bool {
545544
return false
546545
}
547546

548-
// HandleSpecificHash returns the mandated hash if the algorithm requires it;
549-
// otherwise, it returns the selectedHash.
550-
func (pka PublicKeyAlgorithm) HandleSpecificHash(selectedHash crypto.Hash) crypto.Hash {
551-
switch pka {
552-
case PubKeyAlgoMldsa65Ed25519:
553-
return crypto.SHA3_256
554-
case PubKeyAlgoMldsa87Ed448:
555-
return crypto.SHA3_512
556-
}
557-
return selectedHash
558-
}
559-
560547
// CipherFunction represents the different block ciphers specified for OpenPGP. See
561548
// http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13
562549
type CipherFunction algorithm.CipherFunction

openpgp/packet/private_key.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ func serializeHMACPrivateKey(w io.Writer, priv *symmetric.HMACPrivateKey) (err e
561561
}
562562

563563
// serializeMlkemPrivateKey serializes a ML-KEM + ECC private key according to
564-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-key-material-packets
564+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-key-material-packets
565565
func serializeMlkemPrivateKey(w io.Writer, priv *mlkem_ecdh.PrivateKey) (err error) {
566566
if _, err = w.Write(encoding.NewOctetArray(priv.SecretEc).EncodedBytes()); err != nil {
567567
return err
@@ -571,7 +571,7 @@ func serializeMlkemPrivateKey(w io.Writer, priv *mlkem_ecdh.PrivateKey) (err err
571571
}
572572

573573
// serializeMldsaEddsaPrivateKey serializes a ML-DSA + EdDSA private key according to
574-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-key-material-packets-2
574+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-key-material-packets-2
575575
func serializeMldsaEddsaPrivateKey(w io.Writer, priv *mldsa_eddsa.PrivateKey) error {
576576
if _, err := w.Write(encoding.NewOctetArray(priv.SecretEc).EncodedBytes()); err != nil {
577577
return err
@@ -923,8 +923,14 @@ func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) {
923923
case ExperimentalPubKeyAlgoHMAC:
924924
return pk.parseHMACPrivateKey(data)
925925
case PubKeyAlgoMlkem768X25519:
926+
if !(pk.Version == 4 || pk.Version >= 6) {
927+
return goerrors.New("openpgp: ML-KEM-768+X25519 may only be used with v4 or v6+")
928+
}
926929
return pk.parseMlkemEcdhPrivateKey(data, 32, mlkem_ecdh.MlKemSeedLen)
927930
case PubKeyAlgoMlkem1024X448:
931+
if pk.Version < 6 {
932+
return goerrors.New("openpgp: ML-KEM-1024+X448 may only be used with v6+")
933+
}
928934
return pk.parseMlkemEcdhPrivateKey(data, 56, mlkem_ecdh.MlKemSeedLen)
929935
case PubKeyAlgoMldsa65Ed25519:
930936
return pk.parseMldsaEddsaPrivateKey(data, 32, mldsa_eddsa.MlDsaSeedLen)
@@ -1254,7 +1260,7 @@ func validateCommonSymmetric(seed [32]byte, bindingHash [32]byte) error {
12541260
}
12551261

12561262
// parseMldsaEddsaPrivateKey parses a ML-DSA + EdDSA private key as specified in
1257-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-key-material-packets-2
1263+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-key-material-packets-2
12581264
func (pk *PrivateKey) parseMldsaEddsaPrivateKey(data []byte, ecLen, seedLen int) (err error) {
12591265
if pk.Version != 6 {
12601266
return goerrors.New("openpgp: cannot parse non-v6 ML-DSA + EdDSA key")
@@ -1287,11 +1293,8 @@ func (pk *PrivateKey) parseMldsaEddsaPrivateKey(data []byte, ecLen, seedLen int)
12871293
}
12881294

12891295
// parseMlkemEcdhPrivateKey parses a ML-KEM + ECC private key as specified in
1290-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-key-material-packets
1296+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-key-material-packets
12911297
func (pk *PrivateKey) parseMlkemEcdhPrivateKey(data []byte, ecLen, seedLen int) (err error) {
1292-
if pk.Version != 6 {
1293-
return goerrors.New("openpgp: cannot parse non-v6 ML-KEM + ECDH key")
1294-
}
12951298
pub := pk.PublicKey.PublicKey.(*mlkem_ecdh.PublicKey)
12961299
priv := new(mlkem_ecdh.PrivateKey)
12971300
priv.PublicKey = *pub

openpgp/packet/public_key.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package packet
66

77
import (
88
"bytes"
9-
"crypto"
109
"crypto/dsa"
1110
"crypto/rsa"
1211
"crypto/sha1"
@@ -291,7 +290,7 @@ func NewMlkemEcdhPublicKey(creationTime time.Time, pub *mlkem_ecdh.PublicKey) *P
291290
}
292291

293292
pk := &PublicKey{
294-
Version: 6,
293+
Version: 4,
295294
CreationTime: creationTime,
296295
PubKeyAlgo: PublicKeyAlgorithm(pub.AlgId),
297296
PublicKey: pub,
@@ -615,7 +614,7 @@ func (pk *PublicKey) parseECDH(r io.Reader) (err error) {
615614
}
616615

617616
// parseMlkemEcdh parses a ML-KEM + ECC public key as specified in
618-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-key-material-packets
617+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-key-material-packets
619618
func (pk *PublicKey) parseMlkemEcdh(r io.Reader, ecLen, kLen int) (err error) {
620619
pk.p = encoding.NewEmptyOctetArray(ecLen)
621620
if _, err = pk.p.ReadFrom(r); err != nil {
@@ -800,7 +799,7 @@ func readBindingHash(r io.Reader) (bindingHash [32]byte, err error) {
800799
}
801800

802801
// parseMldsaEddsa parses a ML-DSA + EdDSA public key as specified in
803-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-key-material-packets-2
802+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-key-material-packets-2
804803
func (pk *PublicKey) parseMldsaEddsa(r io.Reader, ecLen, dLen int) (err error) {
805804
pk.p = encoding.NewEmptyOctetArray(ecLen)
806805
if _, err = pk.p.ReadFrom(r); err != nil {
@@ -1140,12 +1139,6 @@ func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err erro
11401139
}
11411140
return nil
11421141
case PubKeyAlgoMldsa65Ed25519, PubKeyAlgoMldsa87Ed448:
1143-
if pk.PubKeyAlgo == PubKeyAlgoMldsa65Ed25519 && sig.Hash != crypto.SHA3_256 {
1144-
return errors.SignatureError(fmt.Sprintf("verification failure: Mldsa65Ed25519 requires sha3-256 message hash: has %s", sig.Hash))
1145-
}
1146-
if pk.PubKeyAlgo == PubKeyAlgoMldsa87Ed448 && sig.Hash != crypto.SHA3_512 {
1147-
return errors.SignatureError(fmt.Sprintf("verification failure: Mldsa87Ed448 requires sha3-512 message hash: has %s", sig.Hash))
1148-
}
11491142
mldsaEddsaPublicKey := pk.PublicKey.(*mldsa_eddsa.PublicKey)
11501143
if !mldsa_eddsa.Verify(mldsaEddsaPublicKey, hashBytes, sig.MldsaSig.Bytes(), sig.EdDSASigR.Bytes()) {
11511144
return errors.SignatureError("MldsaEddsa verification failure")

openpgp/packet/signature.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"crypto/dsa"
1111
"encoding/asn1"
1212
"encoding/binary"
13-
"fmt"
1413
"hash"
1514
"io"
1615
"math/big"
@@ -365,7 +364,7 @@ func (sig *Signature) parse(r io.Reader) (err error) {
365364
}
366365

367366
// parseMldsaEddsaSignature parses an ML-DSA + EdDSA signature as specified in
368-
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-05.html#name-signature-packet-tag-2
367+
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-09.html#name-signature-packet-tag-2
369368
func (sig *Signature) parseMldsaEddsaSignature(r io.Reader, ecLen, dLen int) (err error) {
370369
sig.EdDSASigR = encoding.NewEmptyOctetArray(ecLen)
371370
if _, err = sig.EdDSASigR.ReadFrom(r); err != nil {
@@ -1043,12 +1042,6 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e
10431042
if sig.Version != 6 {
10441043
return errors.StructuralError("cannot use MldsaEdDsa on a non-v6 signature")
10451044
}
1046-
if priv.PubKeyAlgo == PubKeyAlgoMldsa65Ed25519 && sig.Hash != crypto.SHA3_256 {
1047-
return errors.StructuralError(fmt.Sprintf("Mldsa65Ed25519 requires sha3-256 message hash: got %s", sig.Hash))
1048-
}
1049-
if priv.PubKeyAlgo == PubKeyAlgoMldsa87Ed448 && sig.Hash != crypto.SHA3_512 {
1050-
return errors.StructuralError(fmt.Sprintf("Mldsa87Ed448 requires sha3-512 message hash: got %s", sig.Hash))
1051-
}
10521045
sk := priv.PrivateKey.(*mldsa_eddsa.PrivateKey)
10531046
dSig, ecSig, err := mldsa_eddsa.Sign(sk, digest)
10541047

0 commit comments

Comments
 (0)