golang/go · error
mldsa: context too long
Error message
mldsa: context too long
What it means
ML-DSA binds an optional context string into the signed message digest (the ctx in FIPS 204's M' construction). The standard caps this context at 255 bytes so it fits in a single length-prefixed byte. computeMessageHash enforces the cap on behalf of both Sign and Verify; anything longer is rejected before any hashing happens. The same context must be supplied to both Sign and Verify or verification will later fail.
Source
Thrown at src/crypto/internal/fips140/mldsa/mldsa.go:332
return nil, errInvalidPublicKeyLength
}
// We don't precompute A and t1Hat here, because they would make the
// PublicKey over 68KB. Unlike private keys, public keys are often used to
// verify a signature only once, so precomputation doesn't help as often,
// but they can stay around in memory, for example as part of a TLS
// connection's PeerCertificates, so their size is more of a concern.
// Instead, we compute A and t1Hat on demand in Verify.
pub.p = p
copy(pub.raw[:], pk)
pub.tr = computePublicKeyHash(pk)
return pub, nil
}
var (
errContextTooLong = errors.New("mldsa: context too long")
errMessageHashLength = errors.New("mldsa: invalid message hash length")
errRandomLength = errors.New("mldsa: invalid random length")
)
func Sign(priv *PrivateKey, msg []byte, context string) ([]byte, error) {
fipsSelfTest()
fips140.RecordApproved()
var random [32]byte
drbg.Read(random[:])
μ, err := computeMessageHash(priv.pub.tr[:], msg, context)
if err != nil {
return nil, err
}
return signInternal(priv, &μ, &random), nil
}
func SignDeterministic(priv *PrivateKey, msg []byte, context string) ([]byte, error) {
fipsSelfTest()View on GitHub (pinned to b6b368adc5)
Solutions
- Cap the context at 255 bytes; if a longer domain separator is needed, hash it down with SHA-256/SHA3-256 and pass the 32-byte digest as the context (the FIPS 204 scheme does not forbid a hash output as ctx).
- Validate len(context) <= 255 at the API boundary and surface a clear validation error to the caller.
- Keep context a short, stable identifier (application name + version) rather than free-form metadata.
Example fix
// before
sig, err := mldsa.Sign(priv, msg, longDomainString)
// after
if len(context) > 255 {
sum := sha3.Sum256([]byte(longDomainString))
context = string(sum[:])
}
sig, err := mldsa.Sign(priv, msg, context) Defensive patterns
Strategy: validation
Validate before calling
if len(context) > 255 {
return fmt.Errorf("mldsa context limited to 255 bytes, got %d", len(context))
} Type guard
func isValidContext(ctx string) bool { return len(ctx) <= 255 } Prevention
- Keep context a short stable identifier (app name + version).
- Hash long domain separators down to 32 bytes before using them as context.
- Validate context length at the API boundary so the error names the caller's input.
When it happens
Trigger: Calling mldsa.Sign(priv, msg, context) or mldsa.Verify(pub, msg, sig, context) with len(context) > 255.
Common situations: Embedding a long URI, JWT, certificate chain, or concatenated metadata blob as the context; copying a 'domain' string from config without length-checking; logging context that grew over time.
Related errors
- mldsa: invalid seed length
- mldsa: invalid public key length
- mldsa: invalid message hash length
- mldsa: invalid signature length
- ecdsa: private key scalar is zero or negative
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/db15ab90c94f7030.
Report an issue: GitHub.