{"record":{"id":"d13c40c094cb28dc","repo":"golang/go","slug":"invalid-element-encoding","errorCode":null,"errorMessage":"invalid {{ .Element }} encoding","messagePattern":"invalid (.+?)\\} encoding","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/nistec/fiat/generate.go","lineNumber":219,"sourceCode":"\t// rather than happen on the heap.\n\tvar out [{{ .Prefix }}ElementLen]byte\n\treturn e.bytes(&out)\n}\n\nfunc (e *{{ .Element }}) bytes(out *[{{ .Prefix }}ElementLen]byte) []byte {\n\tvar tmp {{ .Prefix }}NonMontgomeryDomainFieldElement\n\t{{ .Prefix }}FromMontgomery(&tmp, &e.x)\n\t{{ .Prefix }}ToBytes(out, (*{{ .Prefix }}UntypedFieldElement)(&tmp))\n\t{{ .Prefix }}InvertEndianness(out[:])\n\treturn out[:]\n}\n\n// SetBytes sets e = v, where v is a big-endian {{ .BytesLen }}-byte encoding, and returns e.\n// If v is not {{ .BytesLen }} bytes or it encodes a value higher than {{ .Prime }},\n// SetBytes returns nil and an error, and e is unchanged.\nfunc (e *{{ .Element }}) SetBytes(v []byte) (*{{ .Element }}, error) {\n\tif len(v) != {{ .Prefix }}ElementLen {\n\t\treturn nil, errors.New(\"invalid {{ .Element }} encoding\")\n\t}\n\n\t// Check for non-canonical encodings (p + k, 2p + k, etc.) by comparing to\n\t// the encoding of -1 mod p, so p - 1, the highest canonical encoding.\n\tvar minusOneEncoding = new({{ .Element }}).Sub(\n\t\tnew({{ .Element }}), new({{ .Element }}).One()).Bytes()\n\tif subtle.ConstantTimeLessOrEqBytes(v, minusOneEncoding) == 0 {\n\t\treturn nil, errors.New(\"invalid {{ .Element }} encoding\")\n\t}\n\n\tvar in [{{ .Prefix }}ElementLen]byte\n\tcopy(in[:], v)\n\t{{ .Prefix }}InvertEndianness(in[:])\n\tvar tmp {{ .Prefix }}NonMontgomeryDomainFieldElement\n\t{{ .Prefix }}FromBytes((*{{ .Prefix }}UntypedFieldElement)(&tmp), &in)\n\t{{ .Prefix }}ToMontgomery(&e.x, &tmp)\n\treturn e, nil\n}","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/nistec/fiat/generate.go#L201-L237","documentation":"Generated into each fiat-curve element type (P224/P256/P384/P521) from generate.go:219. Thrown by (*Element).SetBytes when the input is not exactly the curve's element length (ElementLen). This is the field-element parser rejecting wrong-size big-endian scalars/coordinates before any range check.","triggerScenarios":"Passing a 32-byte value to a P-521 element (66 bytes), a 31-byte value to P-256 (32 bytes), a hex string instead of raw bytes, or a value with a leading zero stripped.","commonSituations":"Cross-curve mix-ups (P-256 value fed to P-384 routine), big.Int.Bytes() that dropped a leading zero, un-decoded hex/base64, or assuming one curve's ElementLen for all curves.","solutions":["Right-pad/truncate the value to exactly ElementLen bytes for the target curve before calling SetBytes.","When converting from big.Int, use a fixed-size FillBytes call and check its returned length.","Confirm the byte slice is raw big-endian, not hex/base64.","Dispatch on curve ID and use the matching ElementLen constant."],"exampleFix":"// before\nx, err := new(fiat.P256Element).SetBytes(v) // v from big.Int.Bytes(), short by 1\n// after\nbuf := make([]byte, fiat.P256ElementLen)\nif !bi.FillBytes(buf) { return errors.New(\"value too large for P-256\") }\nx, err := new(fiat.P256Element).SetBytes(buf)","handlingStrategy":"validation","validationCode":"// Pad to the curve's ElementLen before SetBytes.\nbuf := make([]byte, fiat.P256ElementLen)\nif !bi.FillBytes(buf) {\n    return errors.New(\"value too large for field\")\n}\ne, err := new(fiat.P256Element).SetBytes(buf)","typeGuard":"func isCurveElementBytes(b []byte, elLen int) bool { return len(b) == elLen }","tryCatchPattern":"e, err := new(fiat.P256Element).SetBytes(v)\nif err != nil {\n    return fmt.Errorf(\"field element rejected (len=%d, want=%d): %w\", len(v), fiat.P256ElementLen, err)\n}","preventionTips":["Convert big.Int to fixed-length bytes with FillBytes, not Bytes().","Dispatch on curve ID and use the matching ElementLen constant.","Never pass hex/base64 strings where raw bytes are expected."],"tags":["elliptic-curve","fips140","crypto","nistec","fiat","input-validation","code-generation"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}