golang/go · error
mlkem: invalid NIST decapsulation key length
Error message
mlkem: invalid NIST decapsulation key length
What it means
Thrown by TestingOnlyNewDecapsulationKey768 when the input byte slice is not exactly decapsulationKeySize768 bytes. This is the NIST expanded-format constructor used only for ACVP testing; it rejects wrong-size blobs before any coefficient decode.
Source
Thrown at src/crypto/internal/fips140/mlkem/mlkem768.go:223
return nil, errors.New("mlkem: invalid seed length")
}
d := (*[32]byte)(seed[:32])
z := (*[32]byte)(seed[32:])
kemKeyGen(dk, d, z)
fips140.RecordApproved()
return dk, nil
}
// TestingOnlyNewDecapsulationKey768 parses a decapsulation key from its expanded NIST format.
//
// Bytes() must not be called on the returned key, as it will not produce the
// original seed.
//
// This function should only be used for ACVP testing. Prefer NewDecapsulationKey768 for all
// other purposes.
func TestingOnlyNewDecapsulationKey768(b []byte) (*DecapsulationKey768, error) {
if len(b) != decapsulationKeySize768 {
return nil, errors.New("mlkem: invalid NIST decapsulation key length")
}
dk := &DecapsulationKey768{}
for i := range dk.s {
var err error
dk.s[i], err = polyByteDecode[nttElement](b[:encodingSize12])
if err != nil {
return nil, errors.New("mlkem: invalid secret key encoding")
}
b = b[encodingSize12:]
}
ek, err := NewEncapsulationKey768(b[:EncapsulationKeySize768])
if err != nil {
return nil, err
}
dk.ρ = ek.ρ
dk.h = ek.hView on GitHub (pinned to b6b368adc5)
Solutions
- Verify the blob length is decapsulationKeySize768 before calling.
- Confirm the blob is the NIST expanded format, not the 64-byte d||z seed (use NewDecapsulationKey768 for the seed).
- Use the matching constructor for the ML-KEM parameter set indicated by the vector.
- Re-obtain the vector from a vetted ACVP source for ML-KEM-768.
Example fix
// before
dk, err := mlkem768.TestingOnlyNewDecapsulationKey768(blob) // blob is for 1024
// after
if len(blob) != mlkem768.DecapsulationKeySize768() {
return fmt.Errorf("need ML-KEM-768 expanded blob of %d bytes", mlkem768.DecapsulationKeySize768())
}
dk, err := mlkem768.TestingOnlyNewDecapsulationKey768(blob) Defensive patterns
Strategy: validation
Validate before calling
if len(b) != mlkem768.DecapsulationKeySize768() {
return fmt.Errorf("len %d != %d", len(b), mlkem768.DecapsulationKeySize768())
} Type guard
func isLikelyMLKEM768Blob(b []byte) bool {
return len(b) == mlkem768.DecapsulationKeySize768()
} Try / catch
dk, err := mlkem768.TestingOnlyNewDecapsulationKey768(b)
if err != nil {
return fmt.Errorf("ACVP vector rejected (param=768, len=%d): %w", len(b), err)
} Prevention
- Use NewDecapsulationKey768 with a 64-byte seed for non-ACVP use.
- Tag persisted vectors with their ML-KEM parameter set.
- Do not conflate the 64-byte seed path with the expanded NIST format path.
When it happens
Trigger: Passing a 1024-size expanded blob to the 768 constructor, a seed (64 bytes) instead of the expanded format, or a truncated/transport-wrapped blob.
Common situations: Cross-parameter-set confusion, mistaking the seed path for the expanded path, or handing an ACVP vector with the trailing fields stripped.
Related errors
- mlkem: invalid secret key encoding
- mlkem: inconsistent H(ek) in encoded bytes
- mlkem: invalid encapsulation key length
- mlkem: invalid secret key encoding
- mlkem: inconsistent H(ek) in encoded bytes
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/0d853deb2d41b54a.
Report an issue: GitHub.