OpenBSD manual page server

Manual Page Search Parameters

EC_GROUP_NEW_BY_CURVE_NAME(3) Library Functions Manual EC_GROUP_NEW_BY_CURVE_NAME(3)

EC_GROUP_new_by_curve_name, EC_GROUP_free, EC_GROUP_dup, EC_GROUP_cmp, EC_get_builtin_curves, EC_curve_nid2nist, EC_curve_nist2nidinstantiate named curves built into libcrypto

#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/objects.h>

EC_GROUP *
EC_GROUP_new_by_curve_name(int nid);

void
EC_GROUP_free(EC_GROUP *group);

EC_GROUP *
EC_GROUP_dup(const EC_GROUP *group);

int
EC_GROUP_cmp(const EC_GROUP *group1, const EC_GROUP *group2, BN_CTX *ctx);

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


size_t
EC_get_builtin_curves(EC_builtin_curve *curves, size_t ncurves);

int
EC_curve_nist2nid(const char *name);

const char *
EC_curve_nid2nist(int nid);

Most elliptic curves used in cryptographic protocols have a standardized representation as a , where an ASN.1 Object Identifier (OID) is used instead of detailed domain parameters. This OID is represented internally by a Numerical Identifier (NID), and the parameters themselves must be built into the library. In the EC library the refers to this NID.

() returns a new EC_GROUP object representing the named curve corresponding to nid, using the parameters built into the library. It is equivalent to passing the appropriate parameters to EC_GROUP_new_curve_GFp(3), EC_GROUP_set_curve_name(3), EC_GROUP_set_generator(3) and EC_GROUP_set_seed(3).

() frees group and all the memory associated with it. If group is NULL, no action occurs.

() creates a deep copy of group.

() is intended to determine whether group1 and group2 represent the same elliptic curve, making use of the optional ctx. If the curve name is set on both curves, they are compared as integers, then the prime field, the coefficients of the Weierstrass equation, the generators, their order and their cofactors are compared using BN_cmp(3) or EC_POINT_cmp(3), respectively.

() returns the number of builtin curves. If curves is NULL or ncurves is zero, it performs no other action. Otherwise, after reducing ncurves to the number of builtin curves if necessary, it copies the nid and a pointer to the comment of the first ncurves built-in curves to the array of EC_builtin_curve objects pointed to by curves and leaves the remainder of the array uninitialized.

Some curves can be identified by their NIST name in addition to the numerical identifier (NID). () and () translate between the two. The builtin NIST curves over a prime field are:

name
"P-224"
"P-256" also known as secp256r1
"P-384"
"P-521"

() and () also accept the binary curves defined in FIPS 186-4 and deprecated in SP800-186, as well as "P-192" and NID_X9_62_prime192v1, although all these no longer correspond to builtin curves in LibreSSL.

EC_GROUP_new_by_curve_name() returns a newly allocated group or NULL if there is no built-in group with NID nid, or if memory allocation fails.

EC_GROUP_dup() returns a newly allocated group or NULL if memory allocation fails.

EC_GROUP_cmp() returns 1 if the groups are distinct, 0 if the groups are considered identical and -1 on memory allocation error.

EC_get_builtin_curves() returns the number of builtin curves.

EC_curve_nid2nist() returns a string constant containing the NIST name if nid identifies a NIST curve or NULL otherwise.

EC_curve_nist2nid() returns the NID corresponding to the NIST curve name, or NID_undef.

Print the list of builtin curves, their NIDs, their NIST name and a comment describing each curve:

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <openssl/ec.h>

int
main(void)
{
	EC_builtin_curve *curves;
	size_t ncurves, i;

	if (pledge("stdio", NULL) == -1)
		err(1, "pledge");

	ncurves = EC_get_builtin_curves(NULL, 0);
	if ((curves = calloc(ncurves, sizeof(*curves))) == NULL)
		err(1, NULL);
	(void)EC_get_builtin_curves(curves, ncurves);

	printf("curve\tnid\tNIST\tcomment\n");
	for (i = 0; i < ncurves; i++) {
		const char *nist_name = EC_curve_nid2nist(curves[i].nid);

		printf("%2zu\t%d\t%s\t%s\n", i, curves[i].nid,
		    nist_name != NULL ? nist_name : "", curves[i].comment);
	}

	free(curves);

	return 0;
}

crypto(3), d2i_ECPKParameters(3), EC_GROUP_check(3), EC_GROUP_get_curve_name(3), EC_GROUP_new_curve_GFp(3), EC_KEY_METHOD_new(3), EC_KEY_new(3), EC_POINT_add(3), EC_POINT_get_affine_coordinates(3), EC_POINT_new(3), EC_POINT_point2oct(3), ECDH_compute_key(3), ECDSA_SIG_new(3), OBJ_nid2obj(3)

SEC 1: Elliptic Curve Cryptography, Version 2.0, https://www.secg.org/sec1-v2.pdf, May 21, 2009.

SEC 2: Recommended Elliptic Curve Domain Parameters, Version 2.0, https://www.secg.org/sec2-v2.pdf, Jan 27, 2010.

EC_GROUP_free() first appeared in OpenSSL 0.9.7 and has been available since OpenBSD 3.2.

EC_GROUP_new_by_curve_name(), EC_GROUP_cmp(), EC_GROUP_dup(), and EC_get_builtin_curves() first appeared in OpenSSL 0.9.8 and have been available since OpenBSD 4.5.

EC_curve_nid2nist() and EC_curve_nist2nid() first appeared in OpenSSL 1.1.0 and have been available since OpenBSD 5.8.

EC_GROUP_cmp() compares the coefficients of the Weierstrass equation as integers, not as elements of the prime field. It also treats the generator as mandatory while it is generally optional in the EC library. Aspects of the ASN.1 encoding controlled by the functions in EC_GROUP_get_asn1_flag(3), in particular seed, ASN.1 flag, and point conversion form, are ignored in the comparison. Group objects may therefore compare as equal and produce completely different ASN.1 encodings via i2d_ECPKParameters(3) and related functions. In fact, either of these encodings might be valid or not, accepted or rejected by d2i_ECPKParameters(3), or the encoding might fail on one or both of the group objects.

April 25, 2025 OpenBSD-current