golang/go · error
mlkem: invalid ciphertext length
Error message
mlkem: invalid ciphertext length
What it means
Thrown by Decapsulate1024 when the ciphertext byte slice is not exactly CiphertextSize1024 bytes. Length is checked before the SHA3/decapsulation machinery runs; an off-size input cannot be a valid ML-KEM-1024 ciphertext.
Source
Thrown at src/crypto/internal/fips140/mlkem/mlkem1024.go:404
v := polyAdd(polyAdd(inverseNTT(vNTT), e2), μ)
c := cc[:0]
for _, f := range u {
c = ringCompressAndEncode11(c, f)
}
c = ringCompressAndEncode5(c, v)
return c
}
// Decapsulate generates a shared key from a ciphertext and a decapsulation key.
// If the ciphertext is not valid, Decapsulate returns an error.
//
// The shared key must be kept secret.
func (dk *DecapsulationKey1024) Decapsulate(ciphertext []byte) (sharedKey []byte, err error) {
fipsSelfTest()
if len(ciphertext) != CiphertextSize1024 {
return nil, errors.New("mlkem: invalid ciphertext length")
}
c := (*[CiphertextSize1024]byte)(ciphertext)
// Note that the hash check (step 3 of the decapsulation input check from
// FIPS 203, Section 7.3) is foregone as a DecapsulationKey is always
// validly generated by ML-KEM.KeyGen_internal.
return kemDecaps1024(dk, c), nil
}
// kemDecaps1024 produces a shared key from a ciphertext.
//
// It implements ML-KEM.Decaps_internal according to FIPS 203, Algorithm 18.
func kemDecaps1024(dk *DecapsulationKey1024, c *[CiphertextSize1024]byte) (K []byte) {
fips140.RecordApproved()
m := pkeDecrypt1024(&dk.decryptionKey1024, c)
g := sha3.New512()
g.Write(m[:])
g.Write(dk.h[:])
G := g.Sum(make([]byte, 0, 64))View on GitHub (pinned to b6b368adc5)
Solutions
- Assert len(ciphertext) == CiphertextSize1024 before calling Decapsulate.
- Confirm the ciphertext was produced by Encapsulate1024 against a 1024 encapsulation key.
- Strip any framing/header before passing the raw ciphertext.
- Decode base64/hex into a []byte of the expected length.
Example fix
// before
shared, err := dk.Decapsulate(ct) // ct is 768-size by mistake
// after
if len(ct) != mlkem1024.CiphertextSize1024 {
return fmt.Errorf("ct len %d != %d", len(ct), mlkem1024.CiphertextSize1024)
}
shared, err := dk.Decapsulate(ct) Defensive patterns
Strategy: validation
Validate before calling
if len(ct) != mlkem1024.CiphertextSize1024 {
return fmt.Errorf("ciphertext len %d != %d", len(ct), mlkem1024.CiphertextSize1024)
} Type guard
func isMLKEM1024Ciphertext(b []byte) bool {
return len(b) == mlkem1024.CiphertextSize1024
} Try / catch
shared, err := dk.Decapsulate(ct)
if err != nil {
return fmt.Errorf("decapsulate failed (ct len=%d): %w", len(ct), err)
} Prevention
- Pair the decapsulator and ciphertext parameter set explicitly (1024 with 1024).
- Strip transport framing before calling Decapsulate.
- Decode base64/hex into a fixed-length buffer and assert the size.
When it happens
Trigger: Passing a 768-size ciphertext to a 1024 decapsulator, a ciphertext with a transport header still attached, a hex string that was not decoded, or a buffer that was sliced to the wrong bound.
Common situations: Cross-parameter-set mix-ups (decapsulator and ciphertext from different ML-KEM variants), network framing not stripped, base64 not decoded, or an off-by-one slice around a ciphertext blob.
Related errors
- mlkem: invalid ciphertext length
- mlkem: invalid encapsulation key length
- mlkem: invalid seed length
- mlkem: invalid NIST decapsulation key length
- mlkem: invalid encapsulation key length
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/a5e68ca4f27a8dc8.
Report an issue: GitHub.