golang/go · error
mlkem: invalid seed length
Error message
mlkem: invalid seed length
What it means
ML-KEM key generation derives the decapsulation key from a 64-byte seed split into d (32 bytes, key material) and z (32 bytes, implicit-rejection secret). NewDecapsulationKey1024 checks len(seed) == SeedSize (64) before splitting; any other length is rejected. This mirrors the d||z form mandated by FIPS 203.
Source
Thrown at src/crypto/internal/fips140/mlkem/mlkem1024.go:146
// exclusively for use in tests.
func GenerateKeyInternal1024(d, z *[32]byte) *DecapsulationKey1024 {
fipsSelfTest()
dk := &DecapsulationKey1024{}
kemKeyGen1024(dk, d, z)
return dk
}
// NewDecapsulationKey1024 parses a decapsulation key from a 64-byte
// seed in the "d || z" form. The seed must be uniformly random.
func NewDecapsulationKey1024(seed []byte) (*DecapsulationKey1024, error) {
// The actual logic is in a separate function to outline this allocation.
dk := &DecapsulationKey1024{}
return newKeyFromSeed1024(dk, seed)
}
func newKeyFromSeed1024(dk *DecapsulationKey1024, seed []byte) (*DecapsulationKey1024, error) {
if len(seed) != SeedSize {
return nil, errors.New("mlkem: invalid seed length")
}
d := (*[32]byte)(seed[:32])
z := (*[32]byte)(seed[32:])
kemKeyGen1024(dk, d, z)
fips140.RecordApproved()
return dk, nil
}
// TestingOnlyNewDecapsulationKey1024 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 NewDecapsulationKey1024 for all
// other purposes.
func TestingOnlyNewDecapsulationKey1024(b []byte) (*DecapsulationKey1024, error) {
if len(b) != decapsulationKeySize1024 {
return nil, errors.New("mlkem: invalid NIST decapsulation key length")View on GitHub (pinned to b6b368adc5)
Solutions
- Generate a 64-byte seed via crypto/rand and pass it whole; d and z are interleaved by the library.
- To load an already-expanded NIST key, use TestingOnlyNewDecapsulationKey1024 instead.
- Decode hex/base64 before calling and assert the decoded length is 64.
Example fix
// before seed := make([]byte, 32) // missing z dk, err := mlkem.NewDecapsulationKey1024(seed) // after var seed [mlkem.SeedSize]byte io.ReadFull(rand.Reader, seed[:]) dk, err := mlkem.NewDecapsulationKey1024(seed[:])
Defensive patterns
Strategy: validation
Validate before calling
if len(seed) != mlkem.SeedSize { // 64
return fmt.Errorf("mlkem seed must be %d bytes, got %d", mlkem.SeedSize, len(seed))
} Type guard
func isMLKEMSeed(seed *[64]byte) bool { return seed != nil } Prevention
- Type the seed as [64]byte so length is compile-time enforced.
- Generate seeds only via crypto/rand into the full 64-byte buffer.
- Use TestingOnlyNewDecapsulationKey1024 for expanded NIST keys, not the seed API.
When it happens
Trigger: Calling mlkem.NewDecapsulationKey1024(seed) (or the 512/768 siblings) with a slice whose length is not 64 — e.g. 32 bytes, or the expanded NIST key form.
Common situations: Passing only d (32 bytes) instead of d||z; confusing with ML-DSA's 32-byte seed; passing the expanded key bytes (which are much larger) to this seed-based constructor; hex/base64 not decoded.
Related errors
- mlkem: invalid encoding length
- mldsa: invalid seed length
- mldsa: invalid public key length
- mldsa: invalid signature length
- mlkem: invalid NIST decapsulation key length
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/497fc2661d915f25.
Report an issue: GitHub.