golang/go · error
mlkem: invalid secret key encoding
Error message
mlkem: invalid secret key encoding
What it means
Thrown by TestingOnlyNewDecapsulationKey768 when polyByteDecode fails while parsing one of the k secret polynomial shares (s[i]) from the NIST expanded blob. Each share must be a valid 12-bit-per-coefficient NTT element in encodingSize12 bytes. This is the 768 analogue of error 380.
Source
Thrown at src/crypto/internal/fips140/mlkem/mlkem768.go:231
// 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.h
dk.encryptionKey = ek.encryptionKey
b = b[EncapsulationKeySize768:]
if !bytes.Equal(dk.h[:], b[:32]) {
return nil, errors.New("mlkem: inconsistent H(ek) in encoded bytes")
}
b = b[32:]
View on GitHub (pinned to b6b368adc5)
Solutions
- Confirm the vector was generated for ML-KEM-768 under the final FIPS 203 serialization.
- Verify each 12-bit coefficient block decodes values in [0, 3328].
- Re-fetch the ACVP vector from a trusted source.
- Switch to NewDecapsulationKey768 with a 64-byte seed to bypass the expanded-format parsing.
Example fix
// before
dk, err := mlkem768.TestingOnlyNewDecapsulationKey768(blob)
// after (validate before parsing)
if len(blob) != mlkem768.DecapsulationKeySize768() {
return errors.New("blob length wrong for ML-KEM-768")
}
dk, err := mlkem768.TestingOnlyNewDecapsulationKey768(blob)
if err != nil { return fmt.Errorf("expanded blob decode failed: %w", err) } Defensive patterns
Strategy: try-catch
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("malformed ML-KEM-768 ACVP vector (len=%d): %w", len(b), err)
} Prevention
- Re-fetch ACVP vectors from a trusted NIST CAVP source after each FIPS 203 revision.
- Confirm correct endianness when dumping vectors from another tool.
- Prefer the seed-based constructor unless ACVP testing is required.
When it happens
Trigger: Length check (error 385) passed but a coefficient block encodes a value >= q=3329, the 12-bit packing is bit-misaligned, or the blob was byte-swapped/endianness-corrupted.
Common situations: Wrong-endian dump of an ACVP vector, a vector from a draft FIPS 203 serialization, corruption in storage/transit, or a 1024 vector fed to the 768 parser with coincidentally-correct total length.
Related errors
- mlkem: invalid secret key encoding
- mlkem: inconsistent H(ek) in encoded bytes
- mlkem: invalid NIST decapsulation key length
- mlkem: inconsistent H(ek) in encoded bytes
- mlkem: invalid encapsulation key length
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/92f9767bdc6adc3e.
Report an issue: GitHub.