Elliptic Curve Operations

In addition to high level operations for signatures, key agreement, and message encryption using elliptic curve cryptography, the library contains lower level interfaces for performing operations such as elliptic curve point multiplication.

Only curves over prime fields are supported.

Warning

You should only use these interfaces if you know what you are doing.

Note

Prior to 3.6.0, Botan used BigInt to represent scalar values, and EC_Point for elliptic curve points in Jacobian projective form. EC_Point still exists, but is intentionally undocumented, and will be removed in Botan4.

class EC_Group
EC_Group::from_OID(const OID &oid)

Initialize an EC_Group using an OID referencing the curve parameters.

EC_Group::from_name(std::string_view name)

Initialize an EC_Group using a name (such as “secp256r1”)

EC_Group::from_PEM(std::string_view pem)

Initialize an EC_Group using a PEM encoded parameter block

EC_Group(const OID &oid, const BigInt &p, const BigInt &a, const BigInt &b, const BigInt &base_x, const BigInt &base_y, const BigInt &order)

Create an application specific elliptic curve.

Warning

Using application specific curves may be hazardous to your health.

This constructor imposes the following restrictions:

  • The prime must be between 128 and 512 bits, and a multiple of 32 bits.

  • As a special extension regarding the above restriction, the prime may alternately be 521 bits, in which case it must be exactly 2**521-1

  • The prime must be congruent to 3 modulo 4

  • The group order must have identical bitlength to the prime

  • No cofactor is allowed

  • An object identifier must be specified

EC_Group(const BigInt &p, const BigInt &a, const BigInt &b, const BigInt &base_x, const BigInt &base_y, const BigInt &order, const BigInt &cofactor, const OID &oid = OID())

This is a deprecated alternative interface for creating application specific elliptic curves.

This does not impose the same restrictions regarding use of arbitrary sized groups, use of a cofactor, etc, and the object identifier is optional.

Warning

If you are using this constructor, and cannot use the non-deprecated constructor due to the restrictions it places on the curve parameters, be aware that this constructor will be dropped in Botan 4. Please open an issue on Github describing your usecase.

EC_Group(std::span<const uint8_t> ber_encoding)

Initialize an EC_Group by decoding a DER encoded parameter block.

std::vector<uint8_t> DER_encode() const

Return the DER encoding of this group.

std::vector<uint8_t> DER_encode(EC_Group_Encoding form) const

Return the DER encoding of this group. This variant is deprecated, but allows the curve to be encoded using the explicit (vs OID) encoding. All support for explicitly encoded elliptic curves is deprecated and will be removed in Botan4.

std::string PEM_encode() const

Return the PEM encoding of this group (base64 of DER encoding plus header/trailer).

const BigInt &get_p() const

Return the prime modulus as a BigInt

const BigInt &get_a() const

Return the a parameter of the elliptic curve equation as a BigInt

const BigInt &get_b() const

Return the b parameter of the elliptic curve equation as a BigInt

const EC_Point &get_base_point() const

Return the groups base point element as a BigInt

const BigInt &get_g_x() const

Return the x coordinate of the base point element as a BigInt

const BigInt &get_g_y() const

Return the y coordinate of the base point element as a BigInt

const BigInt &get_order() const

Return the order of the group generated by the base point as a BigInt

const BigInt &get_cofactor() const

Return the cofactor of the curve. In most cases this will be 1.

Warning

In Botan4 all support for elliptic curves group with a cofactor > 1 will be removed.

const OID &get_curve_oid() const

Return the OID used to identify this curve. May be empty.

bool verify_group(RandomNumberGenerator &rng, bool strong = false) const

Attempt to verify the group seems valid.

static const std::set<std::string> &known_named_groups()

Return a list of known groups, ie groups for which EC_Group::from_name(name) will succeed.

class EC_Scalar

An elliptic curve scalar; that is, an integer in the range [0,n) where n is size of the prime order subgroup generated by the standard group generator.

Note that while zero is a representable value, some of the deserialization functions reject zero.

static std::optional<EC_Scalar> deserialize(const EC_Group &group, std::span<const uint8_t> buf)

Deserialize a scalar. The bytestring must be exactly the length of the group order; neither inputs with excess leading zero bytes nor short encodings are accepted.

Returns nullopt if the length is incorrect or if the integer is not within the range [1,n) where n is the group order.

static EC_Scalar from_bytes_with_trunc(const EC_Group &group, std::span<const uint8_t> buf)

Convert a bytestring to a scalar using the ECDSA truncation rules. This can return zero.

static EC_Scalar from_bytes_mod_order(const EC_Group &group, std::span<const uint8_t> buf)

Treating the input as the big-endian encoding of an integer, reduce that integer modulo n.

The encoded integer should be no greater than n**2.

EC_Scalar(const EC_Group &group, std::span<const uint8_t> buf)

Deserialize a scalar. This is equivalent to deserialize except that it will throw an exception if the input is unacceptable.

static EC_Scalar random(const EC_Group &group, RandomNumberGenerator &rng)

Return a random scalar

static EC_Scalar gk_x_mod_order(const EC_Scalar &scalar, RandomNumberGenerator &rng, std::vector<BigInt> &ws)

Compute the elliptic curve scalar multiplication (g*k) where g is the standard base point on the curve. Then extract the x coordinate of the resulting point, and reduce it modulo the group order.

If the scalar value is zero (resulting in the scalar multiplication producing the identity element) then this function returns zero.

size_t bytes() const

Return the byte length of the scalar

void serialize_to(std::span<uint8_t> buf) const

Serialize the scalar to the provided span. It must have length exactly equal to the value returned by bytes.

bool is_zero() const

Returns true if this scalar value is zero

bool is_nonzero() const

Returns true if this scalar value is zero

EC_Scalar invert() const

Return the multiplicative inverse, or zero if *this is zero

EC_Scalar negate() const

Return the additive inverse

EC_Scalar operator+(const EC_Scalar &x, const EC_Scalar &y)

Addition modulo n

EC_Scalar operator-(const EC_Scalar &x, const EC_Scalar &y)

Subtraction modulo n

EC_Scalar operator*(const EC_Scalar &x, const EC_Scalar &y)

Multiplication modulo n

bool operator==(const EC_Scalar &x, const EC_Scalar &y)

Equality test

class EC_AffinePoint

A point on the elliptic curve.

EC_AffinePoint(const EC_Group &group, std::span<const uint8_t> bytes)

Point deserialization. Throws if invalid, including if the point is not on the curve.

This accepts SEC1 compressed or uncompressed formats

static std::optional<EC_AffinePoint> deserialize(const EC_Group &group, std::span<const uint8_t> bytes)

Point deserialization. Returns nullopt if invalid, including if the point is not on the curve.

This accepts SEC1 compressed or uncompressed formats

static EC_AffinePoint g_mul(const EC_Scalar &scalar, RandomNumberGenerator &rng, std::vector<BigInt> &ws)

Fixed base scalar multiplication. Constant time with blinding.

EC_AffinePoint mul(const EC_Scalar &scalar, RandomNumberGenerator &rng, std::vector<BigInt> &ws) const

Variable base scalar multiplication. Constant time with blinding.

static EC_AffinePoint hash_to_curve_ro(const EC_Group &group, std::string_view hash_fn, std::span<const uint8_t> input, std::span<const uint8_t> domain_sep)

Has to curve (RFC 9380), random oracle variant.

This is currently only supported for a few curves.

static EC_AffinePoint hash_to_curve_nu(const EC_Group &group, std::string_view hash_fn, std::span<const uint8_t> input, std::span<const uint8_t> domain_sep)

Has to curve (RFC 9380), non-uniform variant.

This is currently only supported for a few curves.

size_t field_element_bytes() const

Return the size of the x and y coordinates, in bytes.

void serialize_x_to(std::span<uint8_t> bytes) const

Serialize x coordinate to the output span

void serialize_y_to(std::span<uint8_t> bytes) const

Serialize y coordinate to the output span

void serialize_xy_to(std::span<uint8_t> bytes) const

Serialize x and y coordinates to the output span

void serialize_compressed_to(std::span<uint8_t> bytes) const

Serialize the compressed SEC1 encoding to the output span

void serialize_uncompressed_to(std::span<uint8_t> bytes) const

Serialize the uncompressed SEC1 encoding to the output span