golang/go · error

mlkem: invalid encapsulation key length

Error message

mlkem: invalid encapsulation key length

What it means

Thrown by parseEK1024 (reached via NewEncapsulationKey1024) when the supplied encapsulation-key byte slice length is not exactly EncapsulationKeySize1024. This is the public-key parsing entry point; the length is the first and strictest invariant before any coefficient decode.

Source

Thrown at src/crypto/internal/fips140/mlkem/mlkem1024.go:327

	c = pkeEncrypt1024(cc, &ek.encryptionKey1024, m, r)
	return K, c
}

// NewEncapsulationKey1024 parses an encapsulation key from its encoded form.
// If the encapsulation key is not valid, NewEncapsulationKey1024 returns an error.
func NewEncapsulationKey1024(encapsulationKey []byte) (*EncapsulationKey1024, error) {
	// The actual logic is in a separate function to outline this allocation.
	ek := &EncapsulationKey1024{}
	return parseEK1024(ek, encapsulationKey)
}

// parseEK1024 parses an encryption key from its encoded form.
//
// It implements the initial stages of K-PKE.Encrypt according to FIPS 203,
// Algorithm 14.
func parseEK1024(ek *EncapsulationKey1024, ekPKE []byte) (*EncapsulationKey1024, error) {
	if len(ekPKE) != EncapsulationKeySize1024 {
		return nil, errors.New("mlkem: invalid encapsulation key length")
	}

	h := sha3.New256()
	h.Write(ekPKE)
	h.Sum(ek.h[:0])

	for i := range ek.t {
		var err error
		ek.t[i], err = polyByteDecode[nttElement](ekPKE[:encodingSize12])
		if err != nil {
			return nil, err
		}
		ekPKE = ekPKE[encodingSize12:]
	}
	copy(ek.ρ[:], ekPKE)

	for i := byte(0); i < k1024; i++ {
		for j := byte(0); j < k1024; j++ {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Check len(encapsulationKey) == EncapsulationKeySize1024 before calling.
  2. Ensure the bytes are raw ML-KEM-1024 public key material, not PEM/DER/base64.
  3. If loading from a 768/1024-agnostic source, dispatch on the recorded algorithm OID/length first.
  4. Regenerate the key with the current library version to rule out a serialization-format drift.

Example fix

// before
ek, err := mlkem1024.NewEncapsulationKey1024(pub) // pub is 1184 bytes (768 size)
// after
if len(pub) != mlkem1024.EncapsulationKeySize1024 {
    return fmt.Errorf("pub len %d != %d", len(pub), mlkem1024.EncapsulationKeySize1024)
}
ek, err := mlkem1024.NewEncapsulationKey1024(pub)
Defensive patterns

Strategy: validation

Validate before calling

if len(ek) != mlkem1024.EncapsulationKeySize1024 {
    return fmt.Errorf("encapsulation key len %d != %d", len(ek), mlkem1024.EncapsulationKeySize1024)
}

Type guard

func isMLKEM1024EncapsulationKey(b []byte) bool {
    return len(b) == mlkem1024.EncapsulationKeySize1024
}

Try / catch

ek, err := mlkem1024.NewEncapsulationKey1024(pub)
if err != nil {
    return fmt.Errorf("invalid ML-KEM-1024 encapsulation key (len=%d): %w", len(pub), err)
}

Prevention

When it happens

Trigger: Passing a truncated/padded key, a key encoded for ML-KEM-768, a key still wrapped in a higher-level structure (e.g. X.509 SubjectPublicKeyInfo), or a hex/base64 blob that was decoded with the wrong alphabet or wrong nibble count.

Common situations: Hard-coding the wrong constant (using the 768 size for a 1024 key), forgetting to strip a PEM/DER envelope, mixing up byte and base64 lengths, or upgrading from a draft where EncapsulationKeySize1024 differed.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/5c4b4e44086f63b3. Report an issue: GitHub.