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.

Many of these functions take a workspace, either a vector of words or a vector of BigInts. These are used to minimize memory allocations during common operations.

Warning

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

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(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.

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(const std::vector<uint8_t> &ber_encoding)

Initialize an EC_Group by decoding a DER encoded parameter block.

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

Return the DER encoding of this group.

std::string PEM_encode() const

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

size_t get_p_bits() const

Return size of the prime in bits.

size_t get_p_bytes() const

Return size of the prime in bytes.

size_t get_order_bits() const

Return size of the group order in bits.

size_t get_order_bytes() const

Return size of the group order in bytes.

const BigInt &get_p() const

Return the prime modulus.

const BigInt &get_a() const

Return the a parameter of the elliptic curve equation.

const BigInt &get_b() const

Return the b parameter of the elliptic curve equation.

const EC_Point &get_base_point() const

Return the groups base point element.

const BigInt &get_g_x() const

Return the x coordinate of the base point element.

const BigInt &get_g_y() const

Return the y coordinate of the base point element.

const BigInt &get_order() const

Return the order of the group generated by the base point.

const BigInt &get_cofactor() const

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

Warning

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

BigInt mod_order(const BigInt &x) const

Reduce argument x modulo the curve order.

BigInt inverse_mod_order(const BigInt &x) const

Return inverse of argument x modulo the curve order.

BigInt multiply_mod_order(const BigInt &x, const BigInt &y) const

Multiply x and y and reduce the result modulo the curve order.

bool verify_public_element(const EC_Point &y) const

Return true if y seems to be a valid group element.

const OID &get_curve_oid() const

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

EC_Point point(const BigInt &x, const BigInt &y) const

Create and return a point with affine elements x and y. Note this function does not verify that x and y satisfy the curve equation.

EC_Point point_multiply(const BigInt &x, const EC_Point &pt, const BigInt &y) const

Multi-exponentiation. Returns base_point*x + pt*y. Not constant time. (Ordinarily used for signature verification.)

EC_Point blinded_base_point_multiply(const BigInt &k, RandomNumberGenerator &rng, std::vector<BigInt> &ws) const

Return base_point*k in a way that attempts to resist side channels.

BigInt blinded_base_point_multiply_x(const BigInt &k, RandomNumberGenerator &rng, std::vector<BigInt> &ws) const

Like blinded_base_point_multiply but returns only the x coordinate.

EC_Point blinded_var_point_multiply(const EC_Point &point, const BigInt &k, RandomNumberGenerator &rng, std::vector<BigInt> &ws) const

Return point*k in a way that attempts to resist side channels.

BigInt random_scalar(RandomNumberGenerator &rng) const

Return a random scalar (ie an integer between 1 and the group order).

EC_Point zero_point() const

Return the zero point (aka the point at infinity).

EC_Point OS2ECP(const uint8_t bits[], size_t len) const

Decode a point from the binary encoding. This function verifies that the decoded point is a valid element on the curve.

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(name) will succeed.

class EC_Point

Stores elliptic curve points in Jacobian representation.

std::vector<uint8_t> encode(EC_Point::Compression_Type format) const

Encode a point in a way that can later be decoded with EC_Group::OS2ECP.

EC_Point &operator+=(const EC_Point &rhs)

Point addition.

EC_Point &operator-=(const EC_Point &rhs)

Point subtraction.

EC_Point &operator*=(const BigInt &scalar)

Point multiplication using Montgomery ladder.

Warning

Prefer the blinded functions in EC_Group

EC_Point &negate()

Negate this point.

BigInt get_affine_x() const

Return the affine x coordinate of the point.

BigInt get_affine_y() const

Return the affine y coordinate of the point.

void force_affine()

Convert the point to its equivalent affine coordinates. Throws if this is the point at infinity.

static void force_all_affine(std::vector<EC_Point> &points, secure_vector<word> &ws)

Force several points to be affine at once. Uses Montgomery’s trick to reduce number of inversions required, so this is much faster than calling force_affine on each point in sequence.

bool is_affine() const

Return true if this point is in affine coordinates.

bool is_zero() const

Return true if this point is zero (aka point at infinity).

bool on_the_curve() const

Return true if this point is on the curve.

void randomize_repr(RandomNumberGenerator &rng)

Randomize the point representation.

bool operator==(const EC_Point &other) const

Point equality. This compares the affine representations.