ec.h

All headers

Low-level operations on elliptic curves.

  1. Elliptic curve groups
  2. EC_GROUP_new_by_curve_name
  3. EC_GROUP_free
  4. EC_GROUP_dup
  5. EC_GROUP_cmp
  6. EC_GROUP_get0_generator
  7. EC_GROUP_get0_order
  8. EC_GROUP_get_cofactor
  9. EC_GROUP_get_curve_GFp
  10. EC_GROUP_get_curve_name
  11. EC_GROUP_get_degree
  12. Points on elliptic curves
  13. EC_POINT_new
  14. EC_POINT_free
  15. EC_POINT_copy
  16. EC_POINT_dup
  17. EC_POINT_set_to_infinity
  18. EC_POINT_is_at_infinity
  19. EC_POINT_is_on_curve
  20. EC_POINT_cmp
  21. EC_POINT_make_affine
  22. EC_POINTs_make_affine
  23. Point conversion
  24. EC_POINT_get_affine_coordinates_GFp
  25. EC_POINT_set_affine_coordinates_GFp
  26. EC_POINT_point2oct
  27. EC_POINT_point2cbb
  28. EC_POINT_oct2point
  29. EC_POINT_set_compressed_coordinates_GFp
  30. Group operations
  31. EC_POINT_add
  32. EC_POINT_dbl
  33. EC_POINT_invert
  34. EC_POINT_mul
  35. Deprecated functions
  36. EC_GROUP_new_curve_GFp
  37. EC_GROUP_set_generator
  38. EC_GROUP_get_order
  39. EC_GROUP_set_asn1_flag
  40. OPENSSL_EC_NAMED_CURVE
  41. EC_GROUP_method_of
  42. EC_METHOD_get_field_type
  43. EC_GROUP_set_point_conversion_form
  44. EC_get_builtin_curves
  45. EC_POINT_clear_free

point_conversion_form_t enumerates forms, as defined in X9.62 (ECDSA), for the encoding of a elliptic curve point (x,y)

typedef enum {
  // POINT_CONVERSION_COMPRESSED indicates that the point is encoded as z||x,
  // where the octet z specifies which solution of the quadratic equation y
  // is.
  POINT_CONVERSION_COMPRESSED = 2,

  // POINT_CONVERSION_UNCOMPRESSED indicates that the point is encoded as
  // z||x||y, where z is the octet 0x04.
  POINT_CONVERSION_UNCOMPRESSED = 4,

  // POINT_CONVERSION_HYBRID indicates that the point is encoded as z||x||y,
  // where z specifies which solution of the quadratic equation y is. This is
  // not supported by the code and has never been observed in use.
  //
  // TODO(agl): remove once node.js no longer references this.
  POINT_CONVERSION_HYBRID = 6,
} point_conversion_form_t;

Elliptic curve groups.

EC_GROUP_new_by_curve_name returns a fresh EC_GROUP object for the elliptic curve specified by nid, or NULL on error.

The supported NIDs are:
NID_secp224r1,
NID_X9_62_prime256v1,
NID_secp384r1,
NID_secp521r1

OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_by_curve_name(int nid);

EC_GROUP_free frees group and the data that it points to.

OPENSSL_EXPORT void EC_GROUP_free(EC_GROUP *group);

EC_GROUP_dup returns a fresh EC_GROUP which is equal to a or NULL on error.

OPENSSL_EXPORT EC_GROUP *EC_GROUP_dup(const EC_GROUP *a);

EC_GROUP_cmp returns zero if a and b are the same group and non-zero otherwise.

OPENSSL_EXPORT int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b,
                                BN_CTX *ignored);

EC_GROUP_get0_generator returns a pointer to the internal EC_POINT object in group that specifies the generator for the group.

OPENSSL_EXPORT const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group);

EC_GROUP_get0_order returns a pointer to the internal BIGNUM object in group that specifies the order of the group.

OPENSSL_EXPORT const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group);

EC_GROUP_get_cofactor sets *cofactor to the cofactor of group using ctx, if it's not NULL. It returns one on success and zero otherwise.

OPENSSL_EXPORT int EC_GROUP_get_cofactor(const EC_GROUP *group,
                                         BIGNUM *cofactor, BN_CTX *ctx);

EC_GROUP_get_curve_GFp gets various parameters about a group. It sets *out_p to the order of the coordinate field and *out_a and *out_b to the parameters of the curve when expressed as y² = x³ + ax + b. Any of the output parameters can be NULL. It returns one on success and zero on error.

OPENSSL_EXPORT int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p,
                                          BIGNUM *out_a, BIGNUM *out_b,
                                          BN_CTX *ctx);

EC_GROUP_get_curve_name returns a NID that identifies group.

OPENSSL_EXPORT int EC_GROUP_get_curve_name(const EC_GROUP *group);

EC_GROUP_get_degree returns the number of bits needed to represent an element of the field underlying group.

OPENSSL_EXPORT unsigned EC_GROUP_get_degree(const EC_GROUP *group);

Points on elliptic curves.

EC_POINT_new returns a fresh EC_POINT object in the given group, or NULL on error.

OPENSSL_EXPORT EC_POINT *EC_POINT_new(const EC_GROUP *group);

EC_POINT_free frees point and the data that it points to.

OPENSSL_EXPORT void EC_POINT_free(EC_POINT *point);

EC_POINT_copy sets *dest equal to *src. It returns one on success and zero otherwise.

OPENSSL_EXPORT int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src);

EC_POINT_dup returns a fresh EC_POINT that contains the same values as src, or NULL on error.

OPENSSL_EXPORT EC_POINT *EC_POINT_dup(const EC_POINT *src,
                                      const EC_GROUP *group);

EC_POINT_set_to_infinity sets point to be the "point at infinity" for the given group.

OPENSSL_EXPORT int EC_POINT_set_to_infinity(const EC_GROUP *group,
                                            EC_POINT *point);

EC_POINT_is_at_infinity returns one iff point is the point at infinity and zero otherwise.

OPENSSL_EXPORT int EC_POINT_is_at_infinity(const EC_GROUP *group,
                                           const EC_POINT *point);

EC_POINT_is_on_curve returns one if point is an element of group and and zero otherwise or when an error occurs. This is different from OpenSSL, which returns -1 on error. If ctx is non-NULL, it may be used.

OPENSSL_EXPORT int EC_POINT_is_on_curve(const EC_GROUP *group,
                                        const EC_POINT *point, BN_CTX *ctx);

EC_POINT_cmp returns zero if a is equal to b, greater than zero if not equal and -1 on error. If ctx is not NULL, it may be used.

OPENSSL_EXPORT int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a,
                                const EC_POINT *b, BN_CTX *ctx);

EC_POINT_make_affine converts point to affine form, internally. It returns one on success and zero otherwise. If ctx is not NULL, it may be used.

OPENSSL_EXPORT int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point,
                                        BN_CTX *ctx);

EC_POINTs_make_affine converts num points from points to affine form, internally. It returns one on success and zero otherwise. If ctx is not NULL, it may be used.

OPENSSL_EXPORT int EC_POINTs_make_affine(const EC_GROUP *group, size_t num,
                                         EC_POINT *points[], BN_CTX *ctx);

Point conversion.

EC_POINT_get_affine_coordinates_GFp sets x and y to the affine value of point using ctx, if it's not NULL. It returns one on success and zero otherwise.

OPENSSL_EXPORT int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
                                                       const EC_POINT *point,
                                                       BIGNUM *x, BIGNUM *y,
                                                       BN_CTX *ctx);

EC_POINT_set_affine_coordinates_GFp sets the value of point to be (x, y). The ctx argument may be used if not NULL. It returns one on success or zero on error. Note that, unlike with OpenSSL, it's considered an error if the point is not on the curve.

OPENSSL_EXPORT int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
                                                       EC_POINT *point,
                                                       const BIGNUM *x,
                                                       const BIGNUM *y,
                                                       BN_CTX *ctx);

EC_POINT_point2oct serialises point into the X9.62 form given by form into, at most, len bytes at buf. It returns the number of bytes written or zero on error if buf is non-NULL, else the number of bytes needed. The ctx argument may be used if not NULL.

OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group,
                                         const EC_POINT *point,
                                         point_conversion_form_t form,
                                         uint8_t *buf, size_t len, BN_CTX *ctx);

EC_POINT_point2cbb behaves like EC_POINT_point2oct but appends the serialised point to cbb. It returns one on success and zero on error.

OPENSSL_EXPORT int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group,
                                      const EC_POINT *point,
                                      point_conversion_form_t form,
                                      BN_CTX *ctx);

EC_POINT_oct2point sets point from len bytes of X9.62 format serialisation in buf. It returns one on success and zero otherwise. The ctx argument may be used if not NULL.

OPENSSL_EXPORT int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
                                      const uint8_t *buf, size_t len,
                                      BN_CTX *ctx);

EC_POINT_set_compressed_coordinates_GFp sets point to equal the point with the given x coordinate and the y coordinate specified by y_bit (see X9.62). It returns one on success and zero otherwise.

OPENSSL_EXPORT int EC_POINT_set_compressed_coordinates_GFp(
    const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, int y_bit,
    BN_CTX *ctx);

Group operations.

EC_POINT_add sets r equal to a plus b. It returns one on success and zero otherwise. If ctx is not NULL, it may be used.

OPENSSL_EXPORT int EC_POINT_add(const EC_GROUP *group, EC_POINT *r,
                                const EC_POINT *a, const EC_POINT *b,
                                BN_CTX *ctx);

EC_POINT_dbl sets r equal to a plus a. It returns one on success and zero otherwise. If ctx is not NULL, it may be used.

OPENSSL_EXPORT int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r,
                                const EC_POINT *a, BN_CTX *ctx);

EC_POINT_invert sets a equal to minus a. It returns one on success and zero otherwise. If ctx is not NULL, it may be used.

OPENSSL_EXPORT int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a,
                                   BN_CTX *ctx);

EC_POINT_mul sets r = generator*n + q*m. It returns one on success and zero otherwise. If ctx is not NULL, it may be used.

OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r,
                                const BIGNUM *n, const EC_POINT *q,
                                const BIGNUM *m, BN_CTX *ctx);

Deprecated functions.

EC_GROUP_new_curve_GFp creates a new, arbitrary elliptic curve group based on the equation y² = x³ + a·x + b. It returns the new group or NULL on error.

This new group has no generator. It is an error to use a generator-less group with any functions except for EC_GROUP_free, EC_POINT_new, EC_POINT_set_affine_coordinates_GFp, and EC_GROUP_set_generator.

EC_GROUPs returned by this function will always compare as unequal via EC_GROUP_cmp (even to themselves). EC_GROUP_get_curve_name will always return NID_undef.

Avoid using arbitrary curves and use EC_GROUP_new_by_curve_name instead.

OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p,
                                                const BIGNUM *a,
                                                const BIGNUM *b, BN_CTX *ctx);

EC_GROUP_set_generator sets the generator for group to generator, which must have the given order and cofactor. It may only be used with EC_GROUP objects returned by EC_GROUP_new_curve_GFp and may only be used once on each group. generator must have been created using group.

OPENSSL_EXPORT int EC_GROUP_set_generator(EC_GROUP *group,
                                          const EC_POINT *generator,
                                          const BIGNUM *order,
                                          const BIGNUM *cofactor);

EC_GROUP_get_order sets *order to the order of group, if it's not NULL. It returns one on success and zero otherwise. ctx is ignored. Use EC_GROUP_get0_order instead.

OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order,
                                      BN_CTX *ctx);

EC_GROUP_set_asn1_flag does nothing.

OPENSSL_EXPORT void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag);
#define OPENSSL_EC_NAMED_CURVE 0
typedef struct ec_method_st EC_METHOD;

EC_GROUP_method_of returns NULL.

OPENSSL_EXPORT const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);

EC_METHOD_get_field_type returns NID_X9_62_prime_field.

OPENSSL_EXPORT int EC_METHOD_get_field_type(const EC_METHOD *meth);

EC_GROUP_set_point_conversion_form aborts the process if form is not POINT_CONVERSION_UNCOMPRESSED and otherwise does nothing.

OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form(
    EC_GROUP *group, point_conversion_form_t form);

EC_builtin_curve describes a supported elliptic curve.

typedef struct {
  int nid;
  const char *comment;
} EC_builtin_curve;

EC_get_builtin_curves writes at most max_num_curves elements to out_curves and returns the total number that it would have written, had max_num_curves been large enough.

The EC_builtin_curve items describe the supported elliptic curves.

OPENSSL_EXPORT size_t EC_get_builtin_curves(EC_builtin_curve *out_curves,
                                            size_t max_num_curves);

EC_POINT_clear_free calls EC_POINT_free.

OPENSSL_EXPORT void EC_POINT_clear_free(EC_POINT *point);

Old code expects to get EC_KEY from ec.h.

#include <openssl/ec_key.h>