{"record":{"id":"89a6a13220587ce5","repo":"golang/go","slug":"invalid-p256-element-encoding","errorCode":null,"errorMessage":"invalid P256 element encoding","messagePattern":"invalid P256 element encoding","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/nistec/p256_asm.go","lineNumber":97,"sourceCode":"\t// This implementation operates in the Montgomery domain with R = 2²⁵⁶ mod\n\t// p. Elements in the Montgomery domain take the form a×R and p256Mul\n\t// calculates (a × b × R⁻¹) mod p. rr is R in the domain, or R×R mod p, thus\n\t// p256Mul(e, RR) gives e×R, i.e. converts e into the Montgomery domain.\n\trr := p256Element{0x0000000000000003, 0xfffffffbffffffff,\n\t\t0xfffffffffffffffe, 0x00000004fffffffd}\n\n\tswitch {\n\t// Point at infinity.\n\tcase len(b) == 1 && b[0] == 0:\n\t\treturn p.Set(NewP256Point()), nil\n\n\t// Uncompressed form.\n\tcase len(b) == p256UncompressedLength && b[0] == 4:\n\t\tvar r P256Point\n\t\tp256BigToLittle(&r.x, (*[32]byte)(b[1:33]))\n\t\tp256BigToLittle(&r.y, (*[32]byte)(b[33:65]))\n\t\tif p256LessThanP(&r.x) == 0 || p256LessThanP(&r.y) == 0 {\n\t\t\treturn nil, errors.New(\"invalid P256 element encoding\")\n\t\t}\n\t\tp256Mul(&r.x, &r.x, &rr)\n\t\tp256Mul(&r.y, &r.y, &rr)\n\t\tif err := p256CheckOnCurve(&r.x, &r.y); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tr.z = p256One\n\t\treturn p.Set(&r), nil\n\n\t// Compressed form.\n\tcase len(b) == p256CompressedLength && (b[0] == 2 || b[0] == 3):\n\t\tvar r P256Point\n\t\tp256BigToLittle(&r.x, (*[32]byte)(b[1:33]))\n\t\tif p256LessThanP(&r.x) == 0 {\n\t\t\treturn nil, errors.New(\"invalid P256 element encoding\")\n\t\t}\n\t\tp256Mul(&r.x, &r.x, &rr)\n","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/nistec/p256_asm.go#L79-L115","documentation":"During uncompressed P-256 point decoding (65-byte input with 0x04 prefix), each coordinate is range-checked against the field prime p via p256LessThanP. If either x or y is >= p, the encoding is rejected as invalid because field elements must be strictly less than the modulus. This prevents a class of invalid-curve and small-subgroup attacks.","triggerScenarios":"Calling P256Point.SetBytes with a 65-byte uncompressed point where at least one of the 32-byte coordinate fields encodes a value >= the P-256 prime p (0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF).","commonSituations":"Corrupted or tampered public key bytes; incorrect endianness (little-endian coordinates fed where big-endian is expected); manually constructing point encodings without respecting the field modulus; transmission errors over a network channel.","solutions":["Validate or re-fetch the public key from a trusted source","Ensure coordinates are big-endian and within [0, p-1] before encoding","Use higher-level crypto/ecdsa or crypto/ecdh APIs which handle validation internally","Check for transmission corruption by verifying a checksum or signature over the key"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate an uncompressed P-256 point encoding before SetBytes.\n// Note: full on-curve validation is done by the library itself.\nfunc isValidP256Encoding(b []byte) bool {\n    if len(b) == 1 && b[0] == 0 { return true } // infinity\n    if len(b) == 65 && b[0] == 0x04 { return true }\n    if len(b) == 33 && (b[0] == 0x02 || b[0] == 0x03) { return true }\n    return false\n}\n\nif !isValidP256Encoding(keyBytes) { return errors.New(\"bad encoding\") }\n_, err := point.SetBytes(keyBytes) // library does the full field/curve checks","typeGuard":null,"tryCatchPattern":"_, err := point.SetBytes(b)\nif err != nil {\n    // Could be range check, on-curve, or encoding error — all mean reject the key.\n    return fmt.Errorf(\"invalid P-256 point: %w\", err)\n}","preventionTips":["Only accept public keys from authenticated, trusted sources","Use crypto/ecdsa or crypto/ecdh which handle point validation internally","Verify the encoding prefix byte matches the expected format before parsing"],"tags":["crypto","fips140","p256","elliptic-curve","point-decoding","input-validation"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}