mldsa: supplement comments

This commit is contained in:
Sun Yimin 2025-05-08 10:22:30 +08:00 committed by GitHub
parent fc7dc9a54a
commit 0345946203
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 96 additions and 15 deletions

View File

@ -380,6 +380,23 @@ func parsePrivateKey44(sk *PrivateKey44, b []byte) (*PrivateKey44, error) {
return sk, nil
}
// Sign generates a digital signature for the given message and context using the private key.
// It uses a random seed generated from the provided random source.
//
// Parameters:
// - rand: An io.Reader used to generate a random seed for signing.
// - message: The message to be signed. Must not be empty.
// - context: An optional context for domain separation. Must not exceed 255 bytes.
//
// Returns:
// - A byte slice containing the generated signature.
// - An error if the message is empty, the context is too long, or if there is an issue
// reading from the random source.
//
// Note:
// - The function uses SHAKE256 from the SHA-3 family for hashing.
// - The signing process involves generating a unique seed and a hash-based
// message digest (mu) before delegating to the internal signing function.
func (sk *PrivateKey44) Sign(rand io.Reader, message, context []byte) ([]byte, error) {
if len(message) == 0 {
return nil, errors.New("mldsa: empty message")
@ -404,7 +421,11 @@ func (sk *PrivateKey44) Sign(rand io.Reader, message, context []byte) ([]byte, e
return sk.signInternal(seed[:], mu[:])
}
func (sk *PrivateKey44) SignPreHash(rand io.Reader, message, context []byte, oid asn1.ObjectIdentifier) ([]byte, error) {
// SignWithPreHash generates a digital signature for the given message
// using the private key and additional context. It uses a given hashing algorithm
// from the OID to pre-hash the message before signing.
// It is similar to Sign but allows for pre-hashing the message.
func (sk *PrivateKey44) SignWithPreHash(rand io.Reader, message, context []byte, oid asn1.ObjectIdentifier) ([]byte, error) {
if len(message) == 0 {
return nil, errors.New("mldsa: empty message")
}
@ -433,6 +454,7 @@ func (sk *PrivateKey44) SignPreHash(rand io.Reader, message, context []byte, oid
return sk.signInternal(seed[:], mu[:])
}
// See FIPS 204, Algorithm 7 ML-DSA.Sign_internal()
func (sk *PrivateKey44) signInternal(seed, mu []byte) ([]byte, error) {
var s1NTT [l44]nttElement
var s2NTT [k44]nttElement
@ -537,6 +559,8 @@ func (sk *PrivateKey44) signInternal(seed, mu []byte) ([]byte, error) {
}
}
// Verify checks the validity of a given signature for a message and context
// using the public key.
func (pk *PublicKey44) Verify(sig []byte, message, context []byte) bool {
if len(message) == 0 {
return false
@ -560,7 +584,9 @@ func (pk *PublicKey44) Verify(sig []byte, message, context []byte) bool {
return pk.verifyInternal(sig, mu[:])
}
func (pk *PublicKey44) VerifyPreHash(sig []byte, message, context []byte, oid asn1.ObjectIdentifier) bool {
// VerifyWithPreHash verifies a signature using a message and additional context.
// It uses a given hashing algorithm from the OID to pre-hash the message before verifying.
func (pk *PublicKey44) VerifyWithPreHash(sig []byte, message, context []byte, oid asn1.ObjectIdentifier) bool {
if len(message) == 0 {
return false
}
@ -587,6 +613,7 @@ func (pk *PublicKey44) VerifyPreHash(sig []byte, message, context []byte, oid as
return pk.verifyInternal(sig, mu[:])
}
// See FIPS 204, Algorithm 8 ML-DSA.Verify_internal()
func (pk *PublicKey44) verifyInternal(sig, mu []byte) bool {
// Decode the signature
cTilde := sig[:lambda128/4]

View File

@ -220,7 +220,7 @@ var sigGenPreHash44InternalProjectionCases = []struct {
},
}
func TestSignPreHash44(t *testing.T) {
func TestSignWithPreHash44(t *testing.T) {
for _, c := range sigGenPreHash44InternalProjectionCases {
sk, _ := hex.DecodeString(c.sk)
pk, _ := hex.DecodeString(c.pk)
@ -231,7 +231,7 @@ func TestSignPreHash44(t *testing.T) {
if err != nil {
t.Fatalf("NewPrivateKey44 failed: %v", err)
}
sig2, err := priv.SignPreHash(zeroReader, msg, context, c.oid)
sig2, err := priv.SignWithPreHash(zeroReader, msg, context, c.oid)
if err != nil {
t.Fatalf("failed to sign: %v", err)
}
@ -248,7 +248,7 @@ func TestSignPreHash44(t *testing.T) {
if err != nil {
t.Fatalf("NewPublicKey44 failed: %v", err)
}
if !pub.VerifyPreHash(sig, msg, context, c.oid) {
if !pub.VerifyWithPreHash(sig, msg, context, c.oid) {
t.Error("signature verification failed")
}
}

View File

@ -295,6 +295,23 @@ func parsePrivateKey65(sk *PrivateKey65, b []byte) (*PrivateKey65, error) {
return sk, nil
}
// Sign generates a digital signature for the given message and context using the private key.
// It uses a random seed generated from the provided random source.
//
// Parameters:
// - rand: An io.Reader used to generate a random seed for signing.
// - message: The message to be signed. Must not be empty.
// - context: An optional context for domain separation. Must not exceed 255 bytes.
//
// Returns:
// - A byte slice containing the generated signature.
// - An error if the message is empty, the context is too long, or if there is an issue
// reading from the random source.
//
// Note:
// - The function uses SHAKE256 from the SHA-3 family for hashing.
// - The signing process involves generating a unique seed and a hash-based
// message digest (mu) before delegating to the internal signing function.
func (sk *PrivateKey65) Sign(rand io.Reader, message, context []byte) ([]byte, error) {
if len(message) == 0 {
return nil, errors.New("mldsa: empty message")
@ -319,7 +336,11 @@ func (sk *PrivateKey65) Sign(rand io.Reader, message, context []byte) ([]byte, e
return sk.signInternal(seed[:], mu[:])
}
func (sk *PrivateKey65) SignPreHash(rand io.Reader, message, context []byte, oid asn1.ObjectIdentifier) ([]byte, error) {
// SignWithPreHash generates a digital signature for the given message
// using the private key and additional context. It uses a given hashing algorithm
// from the OID to pre-hash the message before signing.
// It is similar to Sign but allows for pre-hashing the message.
func (sk *PrivateKey65) SignWithPreHash(rand io.Reader, message, context []byte, oid asn1.ObjectIdentifier) ([]byte, error) {
if len(message) == 0 {
return nil, errors.New("mldsa: empty message")
}
@ -348,6 +369,7 @@ func (sk *PrivateKey65) SignPreHash(rand io.Reader, message, context []byte, oid
return sk.signInternal(seed[:], mu[:])
}
// See FIPS 204, Algorithm 7 ML-DSA.Sign_internal()
func (sk *PrivateKey65) signInternal(seed, mu []byte) ([]byte, error) {
var s1NTT [l65]nttElement
var s2NTT [k65]nttElement
@ -452,6 +474,8 @@ func (sk *PrivateKey65) signInternal(seed, mu []byte) ([]byte, error) {
}
}
// Verify checks the validity of a given signature for a message and context
// using the public key.
func (pk *PublicKey65) Verify(sig []byte, message, context []byte) bool {
if len(message) == 0 {
return false
@ -473,7 +497,9 @@ func (pk *PublicKey65) Verify(sig []byte, message, context []byte) bool {
return pk.verifyInternal(sig, mu[:])
}
func (pk *PublicKey65) VerifyPreHash(sig []byte, message, context []byte, oid asn1.ObjectIdentifier) bool {
// VerifyWithPreHash verifies a signature using a message and additional context.
// It uses a given hashing algorithm from the OID to pre-hash the message before verifying.
func (pk *PublicKey65) VerifyWithPreHash(sig []byte, message, context []byte, oid asn1.ObjectIdentifier) bool {
if len(message) == 0 {
return false
}
@ -500,6 +526,7 @@ func (pk *PublicKey65) VerifyPreHash(sig []byte, message, context []byte, oid as
return pk.verifyInternal(sig, mu[:])
}
// See FIPS 204, Algorithm 8 ML-DSA.Verify_internal()
func (pk *PublicKey65) verifyInternal(sig, mu []byte) bool {
// Decode the signature
cTilde := sig[:lambda192/4]

View File

@ -220,7 +220,7 @@ var sigGenPreHash65InternalProjectionCases = []struct {
},
}
func TestSignPreHash65(t *testing.T) {
func TestSignWithPreHash65(t *testing.T) {
for _, c := range sigGenPreHash65InternalProjectionCases {
sk, _ := hex.DecodeString(c.sk)
pk, _ := hex.DecodeString(c.pk)
@ -231,7 +231,7 @@ func TestSignPreHash65(t *testing.T) {
if err != nil {
t.Fatalf("NewPrivateKey65 failed: %v", err)
}
sig2, err := priv.SignPreHash(zeroReader, msg, context, c.oid)
sig2, err := priv.SignWithPreHash(zeroReader, msg, context, c.oid)
if err != nil {
t.Fatalf("failed to sign: %v", err)
}
@ -248,7 +248,7 @@ func TestSignPreHash65(t *testing.T) {
if err != nil {
t.Fatalf("NewPublicKey65 failed: %v", err)
}
if !pub.VerifyPreHash(sig, msg, context, c.oid) {
if !pub.VerifyWithPreHash(sig, msg, context, c.oid) {
t.Error("signature verification failed")
}
}

View File

@ -295,6 +295,23 @@ func parsePrivateKey87(sk *PrivateKey87, b []byte) (*PrivateKey87, error) {
return sk, nil
}
// Sign generates a digital signature for the given message and context using the private key.
// It uses a random seed generated from the provided random source.
//
// Parameters:
// - rand: An io.Reader used to generate a random seed for signing.
// - message: The message to be signed. Must not be empty.
// - context: An optional context for domain separation. Must not exceed 255 bytes.
//
// Returns:
// - A byte slice containing the generated signature.
// - An error if the message is empty, the context is too long, or if there is an issue
// reading from the random source.
//
// Note:
// - The function uses SHAKE256 from the SHA-3 family for hashing.
// - The signing process involves generating a unique seed and a hash-based
// message digest (mu) before delegating to the internal signing function.
func (sk *PrivateKey87) Sign(rand io.Reader, message, context []byte) ([]byte, error) {
if len(message) == 0 {
return nil, errors.New("mldsa: empty message")
@ -319,7 +336,11 @@ func (sk *PrivateKey87) Sign(rand io.Reader, message, context []byte) ([]byte, e
return sk.signInternal(seed[:], mu[:])
}
func (sk *PrivateKey87) SignPreHash(rand io.Reader, message, context []byte, oid asn1.ObjectIdentifier) ([]byte, error) {
// SignWithPreHash generates a digital signature for the given message
// using the private key and additional context. It uses a given hashing algorithm
// from the OID to pre-hash the message before signing.
// It is similar to Sign but allows for pre-hashing the message.
func (sk *PrivateKey87) SignWithPreHash(rand io.Reader, message, context []byte, oid asn1.ObjectIdentifier) ([]byte, error) {
if len(message) == 0 {
return nil, errors.New("mldsa: empty message")
}
@ -348,6 +369,7 @@ func (sk *PrivateKey87) SignPreHash(rand io.Reader, message, context []byte, oid
return sk.signInternal(seed[:], mu[:])
}
// See FIPS 204, Algorithm 7 ML-DSA.Sign_internal()
func (sk *PrivateKey87) signInternal(seed, mu []byte) ([]byte, error) {
var s1NTT [l87]nttElement
var s2NTT [k87]nttElement
@ -452,6 +474,8 @@ func (sk *PrivateKey87) signInternal(seed, mu []byte) ([]byte, error) {
}
}
// Verify checks the validity of a given signature for a message and context
// using the public key.
func (pk *PublicKey87) Verify(sig []byte, message, context []byte) bool {
if len(message) == 0 {
return false
@ -475,7 +499,9 @@ func (pk *PublicKey87) Verify(sig []byte, message, context []byte) bool {
return pk.verifyInternal(sig, mu[:])
}
func (pk *PublicKey87) VerifyPreHash(sig []byte, message, context []byte, oid asn1.ObjectIdentifier) bool {
// VerifyWithPreHash verifies a signature using a message and additional context.
// It uses a given hashing algorithm from the OID to pre-hash the message before verifying.
func (pk *PublicKey87) VerifyWithPreHash(sig []byte, message, context []byte, oid asn1.ObjectIdentifier) bool {
if len(message) == 0 {
return false
}
@ -502,6 +528,7 @@ func (pk *PublicKey87) VerifyPreHash(sig []byte, message, context []byte, oid as
return pk.verifyInternal(sig, mu[:])
}
// See FIPS 204, Algorithm 8 ML-DSA.Verify_internal()
func (pk *PublicKey87) verifyInternal(sig, mu []byte) bool {
// Decode the signature
cTilde := sig[:lambda256/4]

View File

@ -172,7 +172,7 @@ var sigGenPreHash87InternalProjectionCases = []struct {
},
}
func TestSignPreHash87(t *testing.T) {
func TestSignWithPreHash87(t *testing.T) {
for _, c := range sigGenPreHash87InternalProjectionCases {
sk, _ := hex.DecodeString(c.sk)
pk, _ := hex.DecodeString(c.pk)
@ -183,7 +183,7 @@ func TestSignPreHash87(t *testing.T) {
if err != nil {
t.Fatalf("NewPrivateKey87 failed: %v", err)
}
sig2, err := priv.SignPreHash(zeroReader, msg, context, c.oid)
sig2, err := priv.SignWithPreHash(zeroReader, msg, context, c.oid)
if err != nil {
t.Fatalf("failed to sign: %v", err)
}
@ -200,7 +200,7 @@ func TestSignPreHash87(t *testing.T) {
if err != nil {
t.Fatalf("NewPublicKey87 failed: %v", err)
}
if !pub.VerifyPreHash(sig, msg, context, c.oid) {
if !pub.VerifyWithPreHash(sig, msg, context, c.oid) {
t.Error("signature verification failed")
}
}