golang/go · error

invalid encapsulated key size

Error message

invalid encapsulated key size

What it means

Raised by hybridPrivateKey.decap when the encapsulated secret enc is not exactly pqCiphertextSize + curvePointSize bytes. HPKE hybrid enc is the concatenation of the ML-KEM ciphertext and the ECDH ephemeral public point; any other length is malformed.

Source

Thrown at src/crypto/hpke/pq.go:335

func (k *hybridPrivateKey) Bytes() ([]byte, error) {
	if k.seed == nil {
		return nil, errors.New("private key seed not available")
	}
	return k.seed, nil
}

func (k *hybridPrivateKey) PublicKey() PublicKey {
	return &hybridPublicKey{
		kem: k.kem,
		t:   k.t.PublicKey(),
		pq:  k.pq.Encapsulator(),
	}
}

func (k *hybridPrivateKey) decap(enc []byte) ([]byte, error) {
	if len(enc) != k.kem.pqCiphertextSize+k.kem.curvePointSize {
		return nil, errors.New("invalid encapsulated key size")
	}
	ctPQ, ctT := enc[:k.kem.pqCiphertextSize], enc[k.kem.pqCiphertextSize:]
	ssPQ, err := k.pq.Decapsulate(ctPQ)
	if err != nil {
		return nil, err
	}
	var pub *ecdh.PublicKey
	fips140.WithoutEnforcement(func() { // Hybrid of ML-KEM, which is Approved.
		pub, err = k.t.Curve().NewPublicKey(ctT)
	})
	if err != nil {
		return nil, err
	}
	var ssT []byte
	fips140.WithoutEnforcement(func() {
		ssT, err = k.t.ECDH(pub)
	})
	if err != nil {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Ensure the sender and responder use the same hybrid KEM suite so pqCiphertextSize and curvePointSize match.
  2. Validate len(enc) against the suite's expected size before calling Decap.
  3. Re-transmit/derive the encapsulated key if it was truncated or corrupted.
  4. When splitting enc, slice at pqCiphertextSize exactly: ctPQ=enc[:pqCiphertextSize], ctT=enc[pqCiphertextSize:].

Example fix

// before
ss, err := privKem.decap(enc[:1088]) // missing ECDH point -> wrong size

// after
ss, err := hybridKEM.Decap(enc) // enc is the full 1120-byte (X25519) blob
Defensive patterns

Strategy: validation

Validate before calling

func validateHybridEnc(kem KEM, enc []byte) error {
    want := kem.(*hybridKEM).pqCiphertextSize + kem.(*hybridKEM).curvePointSize
    if len(enc) != want {
        return fmt.Errorf("invalid encapsulated key size: got %d want %d", len(enc), want)
    }
    return nil
}

Prevention

When it happens

Trigger: Calling decap (driven by KEM Decap/Open) with enc whose length != kem.pqCiphertextSize + kem.curvePointSize. For X25519: 1088+32=1120; for P-256: 1088+65=1153; for P-384: 1568+97=1665.

Common situations: Truncation or corruption of the enc in transit; using a ciphertext generated for a different hybrid suite; buffer slicing bugs that drop the trailing ECDH point or the leading PQ ciphertext; protocol version mismatch where sender and responder use different suites.

Related errors


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