{"record":{"id":"e452a9e35e5f5332","repo":"golang/go","slug":"mldsa-invalid-input-length-for-bitunpackslow","errorCode":null,"errorMessage":"mldsa: invalid input length for bitUnpackSlow","messagePattern":"mldsa: invalid input length for bitUnpackSlow","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/mldsa/semiexpanded.go","lineNumber":215,"sourceCode":"\t\t\tv[0] = byte(acc)\n\t\t\tv = v[1:]\n\t\t\tacc >>= 8\n\t\t\taccBits -= 8\n\t\t}\n\t}\n\tif accBits > 0 {\n\t\tv[0] = byte(acc)\n\t}\n\treturn out\n}\n\nfunc bitUnpackSlow(v []byte, a, b int) (ringElement, error) {\n\tbitlen := bits.Len(uint(a + b))\n\tif bitlen <= 0 || bitlen > 16 {\n\t\tpanic(\"mldsa: internal error: invalid bitlen\")\n\t}\n\tif len(v) != n*bitlen/8 {\n\t\treturn ringElement{}, errors.New(\"mldsa: invalid input length for bitUnpackSlow\")\n\t}\n\n\tmask := uint32((1 << bitlen) - 1)\n\tmaxValue := uint32(a + b)\n\n\tvar r ringElement\n\tvar acc uint32\n\tvar accBits uint\n\tvIdx := 0\n\n\tfor i := range r {\n\t\tfor accBits < uint(bitlen) {\n\t\t\tif vIdx < len(v) {\n\t\t\t\tacc |= uint32(v[vIdx]) << accBits\n\t\t\t\tvIdx++\n\t\t\t\taccBits += 8\n\t\t\t}\n\t\t}","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/mldsa/semiexpanded.go#L197-L233","documentation":"bitUnpackSlow decodes a single ring element from a tightly packed byte slice where each coefficient occupies bitlen bits. The decoder requires the input length to be exactly n*bitlen/8 (n=256 coefficients); anything else means the slice does not align to the element boundary and 'invalid input length for bitUnpackSlow' is returned. It is used by the semi-expanded key decoder to read s1/s2/t0 regions.","triggerScenarios":"bitUnpackSlow is handed a slice whose length is not 256*bitlen/8 bytes (e.g. 33 bytes for an η=2 element that expects 32), typically because the surrounding semi-expanded blob is truncated or its regions were sliced at the wrong offsets.","commonSituations":"Truncating the semi-expanded key partway through a region; slicing regions with the wrong η/bitlen assumption; corrupt ACVP vector.","solutions":["Validate the total semi-expanded length up front (see error 369) so region offsets are always in-bounds.","Regenerate the blob from a known-good key via TestingOnlyPrivateKeySemiExpandedBytes.","Use complete, untouched NIST/ACVP vectors."],"exampleFix":"// before\npriv, err := mldsa.TestingOnlyNewPrivateKeyFromSemiExpanded(truncated)\n\n// after\nwant := semiExpandedPrivKeySize(params44)\nif len(sk) != want { return fmt.Errorf(\"need %d bytes\", want) }\npriv, err := mldsa.TestingOnlyNewPrivateKeyFromSemiExpanded(sk)","handlingStrategy":"validation","validationCode":"if len(sk) != semiExpandedSizeForVariant(v) {\n    return ErrBadSemiExpandedSize\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate total semi-expanded length up front so region offsets stay in-bounds.","Regenerate blobs from a known-good key via the round-trip helper.","Use complete, untouched ACVP vectors."],"tags":["crypto","mldsa","fips","testing","input-length"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}