{"record":{"id":"f6752edae54bbc19","repo":"golang/go","slug":"p256-point-is-the-point-at-infinity","errorCode":null,"errorMessage":"P256 point is the point at infinity","messagePattern":"P256 point is the point at infinity","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/internal/fips140/nistec/p256.go","lineNumber":186,"sourceCode":"\n\tbuf := append(out[:0], 4)\n\tbuf = append(buf, x.Bytes()...)\n\tbuf = append(buf, y.Bytes()...)\n\treturn buf\n}\n\n// BytesX returns the encoding of the x-coordinate of p, as specified in SEC 1,\n// Version 2.0, Section 2.3.5, or an error if p is the point at infinity.\nfunc (p *P256Point) BytesX() ([]byte, error) {\n\t// This function is outlined to make the allocations inline in the caller\n\t// rather than happen on the heap.\n\tvar out [p256ElementLength]byte\n\treturn p.bytesX(&out)\n}\n\nfunc (p *P256Point) bytesX(out *[p256ElementLength]byte) ([]byte, error) {\n\tif p.z.IsZero() == 1 {\n\t\treturn nil, errors.New(\"P256 point is the point at infinity\")\n\t}\n\n\tzinv := new(fiat.P256Element).Invert(&p.z)\n\tx := new(fiat.P256Element).Mul(&p.x, zinv)\n\n\treturn append(out[:0], x.Bytes()...), nil\n}\n\n// BytesCompressed returns the compressed or infinity encoding of p, as\n// specified in SEC 1, Version 2.0, Section 2.3.3. Note that the encoding of the\n// point at infinity is shorter than all other encodings.\nfunc (p *P256Point) BytesCompressed() []byte {\n\t// This function is outlined to make the allocations inline in the caller\n\t// rather than happen on the heap.\n\tvar out [p256CompressedLength]byte\n\treturn p.bytesCompressed(&out)\n}\n","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/internal/fips140/nistec/p256.go#L168-L204","documentation":"Thrown by P256Point.BytesX() (fiat-based implementation) when the receiver is the point at infinity — the elliptic curve identity element where z == 0. The identity has no affine x-coordinate, so the SEC 1 x-coordinate encoding is mathematically undefined. This is a defensive guard: the library refuses to serialize an unrepresentable value rather than returning garbage.","triggerScenarios":"Calling p.BytesX() on a P256Point whose z field is zero. This happens when ScalarMult yields the identity (scalar ≡ 0 mod n), when NewP256Point() is used without setting coordinates, when a point is added to its inverse, or when a deserialized 0x00-encoded point is passed.","commonSituations":"ECDH key agreement where the peer supplies the identity/zero public key; ECDSA signature verification where the nonce k produces r = 0×G; scalar multiplication with an all-zero or all-0xFF scalar that reduces to zero modulo the group order; calling BytesX() on an uninitialized P256Point.","solutions":["Check whether the point is the identity before calling BytesX — call p.Bytes() and test for the 1-byte 0x00 encoding","Validate the result of ScalarMult before extracting coordinates","Ensure scalar inputs are non-zero and within the valid range [1, n-1] before multiplication","If doing ECDH, reject peer public keys that decode to the identity point"],"exampleFix":"// before\nx, err := point.BytesX()\nif err != nil {\n    return err\n}\n\n// after\nenc := point.Bytes()\nif len(enc) == 1 && enc[0] == 0 {\n    return errors.New(\"derived point is identity; reject key\")\n}\nx, err := point.BytesX()\nif err != nil {\n    return err\n}","handlingStrategy":"validation","validationCode":"// Check if a P256Point is the identity before extracting x-coordinate.\nfunc mustNotBeInfinity(p *nistec.P256Point) error {\n    enc := p.Bytes()\n    if len(enc) == 1 && enc[0] == 0 {\n        return errors.New(\"point is identity; cannot extract x-coordinate\")\n    }\n    return nil\n}\n\n// Usage:\nif err := mustNotBeInfinity(point); err != nil { return err }\nx, err := point.BytesX()","typeGuard":null,"tryCatchPattern":"x, err := point.BytesX()\nif err != nil {\n    // err contains \"point at infinity\" — the scalar or peer key is invalid.\n    // Do NOT retry with the same inputs; reject the operation.\n    return fmt.Errorf(\"cannot extract x-coordinate: %w\", err)\n}","preventionTips":["Always validate the result of ScalarMult before extracting coordinates","Reject peer public keys that decode to the identity point at the protocol layer","In ECDH, check that the shared secret point is not infinity before using it","Ensure scalars are non-zero and in [1, n-1] before scalar multiplication"],"tags":["crypto","fips140","p256","elliptic-curve","point-at-infinity"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}