/* * ECC Domain Parameters * * (C) 2007 Falko Strenzke, FlexSecure GmbH * 2008-2010 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ #ifndef BOTAN_ECC_DOMAIN_PARAMETERS_H_ #define BOTAN_ECC_DOMAIN_PARAMETERS_H_ #include #include #include #include namespace Botan { /** * This class represents elliptic curce domain parameters */ enum EC_Group_Encoding { EC_DOMPAR_ENC_EXPLICIT = 0, EC_DOMPAR_ENC_IMPLICITCA = 1, EC_DOMPAR_ENC_OID = 2 }; class CurveGFp; class EC_Group_Data; class EC_Group_Data_Map; /** * Class representing an elliptic curve * * The internal representation is stored in a shared_ptr, so copying an * EC_Group is inexpensive. */ class BOTAN_PUBLIC_API(2,0) EC_Group final { public: /** * Construct Domain paramers from specified parameters * @param curve elliptic curve * @param base_point a base point * @param order the order of the base point * @param cofactor the cofactor */ BOTAN_DEPRECATED("Use version taking all BigInts") EC_Group(const CurveGFp& curve, const PointGFp& base_point, const BigInt& order, const BigInt& cofactor) : EC_Group(curve.get_p(), curve.get_a(), curve.get_b(), base_point.get_affine_x(), base_point.get_affine_y(), order, cofactor) {} /** * Construct Domain paramers from specified parameters * @param p the elliptic curve p * @param a the elliptic curve a param * @param b the elliptic curve b param * @param base_x the x coordinate of the base point * @param base_y the y coordinate of the base point * @param order the order of the base point * @param cofactor the cofactor * @param oid an optional OID used to identify this curve */ 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()); /** * Decode a BER encoded ECC domain parameter set * @param ber_encoding the bytes of the BER encoding */ explicit EC_Group(const std::vector& ber_encoding); /** * Create an EC domain by OID (or throw if unknown) * @param oid the OID of the EC domain to create */ explicit EC_Group(const OID& oid); /** * Create an EC domain from PEM encoding (as from PEM_encode), or * from an OID name (eg "secp256r1", or "1.2.840.10045.3.1.7") * @param pem_or_oid PEM-encoded data, or an OID */ explicit EC_Group(const std::string& pem_or_oid); /** * Create an uninitialized EC_Group */ EC_Group(); ~EC_Group(); EC_Group(const EC_Group&) = default; EC_Group(EC_Group&&) = default; EC_Group& operator=(const EC_Group&) = default; EC_Group& operator=(EC_Group&&) = default; /** * Create the DER encoding of this domain * @param form of encoding to use * @returns bytes encododed as DER */ std::vector DER_encode(EC_Group_Encoding form) const; /** * Return the PEM encoding (always in explicit form) * @return string containing PEM data */ std::string PEM_encode() const; /** * Return domain parameter curve * @result domain parameter curve */ BOTAN_DEPRECATED("Avoid CurveGFp") const CurveGFp& get_curve() const; /** * Return if a == -3 mod p */ bool a_is_minus_3() const; /** * Return if a == 0 mod p */ bool a_is_zero() const; /** * Return the size of p in bits (same as get_p().bits()) */ size_t get_p_bits() const; /** * Return the size of p in bits (same as get_p().bytes()) */ size_t get_p_bytes() const; /** * Return the size of group order in bits (same as get_order().bits()) */ size_t get_order_bits() const; /** * Return the size of p in bytes (same as get_order().bytes()) */ size_t get_order_bytes() const; /** * Return the prime modulus of the field */ const BigInt& get_p() const; /** * Return the a parameter of the elliptic curve equation */ const BigInt& get_a() const; /** * Return the b parameter of the elliptic curve equation */ const BigInt& get_b() const; /** * Return group base point * @result base point */ const PointGFp& get_base_point() const; /** * Return the x coordinate of the base point */ const BigInt& get_g_x() const; /** * Return the y coordinate of the base point */ const BigInt& get_g_y() const; /** * Return the order of the base point * @result order of the base point */ const BigInt& get_order() const; /* * Reduce x modulo the order */ BigInt mod_order(const BigInt& x) const; /* * Return inverse of x modulo the order */ BigInt inverse_mod_order(const BigInt& x) const; /* * Reduce (x*x) modulo the order */ BigInt square_mod_order(const BigInt& x) const; /* * Reduce (x*y) modulo the order */ BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const; /* * Reduce (x*y*z) modulo the order */ BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const; /** * Return the cofactor * @result the cofactor */ const BigInt& get_cofactor() const; /** * Check if y is a plausible point on the curve * * In particular, checks that it is a point on the curve, not infinity, * and that it has order matching the group. */ bool verify_public_element(const PointGFp& y) const; /** * Return the OID of these domain parameters * @result the OID as a string */ std::string BOTAN_DEPRECATED("Use get_curve_oid") get_oid() const { return get_curve_oid().to_string(); } /** * Return the OID of these domain parameters * @result the OID */ const OID& get_curve_oid() const; /** * Return a point on this curve with the affine values x, y */ PointGFp point(const BigInt& x, const BigInt& y) const; /** * Multi exponentiate. Not constant time. * @return base_point*x + pt*y */ PointGFp point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const; /** * Blinded point multiplication, attempts resistance to side channels * @param k the scalar * @param rng a random number generator * @param ws a temp workspace * @return base_point*k */ PointGFp blinded_base_point_multiply(const BigInt& k, RandomNumberGenerator& rng, std::vector& ws) const; /** * Blinded point multiplication, attempts resistance to side channels * Returns just the x coordinate of the point * * @param k the scalar * @param rng a random number generator * @param ws a temp workspace * @return x coordinate of base_point*k */ BigInt blinded_base_point_multiply_x(const BigInt& k, RandomNumberGenerator& rng, std::vector& ws) const; /** * Blinded point multiplication, attempts resistance to side channels * @param point input point * @param k the scalar * @param rng a random number generator * @param ws a temp workspace * @return point*k */ PointGFp blinded_var_point_multiply(const PointGFp& point, const BigInt& k, RandomNumberGenerator& rng, std::vector& ws) const; /** * Return a random scalar ie an integer in [1,order) */ BigInt random_scalar(RandomNumberGenerator& rng) const; /** * Return the zero (or infinite) point on this curve */ PointGFp zero_point() const; size_t point_size(PointGFp::Compression_Type format) const; PointGFp OS2ECP(const uint8_t bits[], size_t len) const; template PointGFp OS2ECP(const std::vector& vec) const { return this->OS2ECP(vec.data(), vec.size()); } bool initialized() const { return (m_data != nullptr); } /** * Verify EC_Group domain * @returns true if group is valid. false otherwise */ bool verify_group(RandomNumberGenerator& rng, bool strong = false) const; bool operator==(const EC_Group& other) const; /** * Return PEM representation of named EC group * Deprecated: Use EC_Group(name).PEM_encode() if this is needed */ static std::string BOTAN_DEPRECATED("See header comment") PEM_for_named_group(const std::string& name); /** * Return a set of known named EC groups */ static const std::set& known_named_groups(); /* * For internal use only */ static std::shared_ptr EC_group_info(const OID& oid); static size_t clear_registered_curve_data(); private: static EC_Group_Data_Map& ec_group_data(); static std::shared_ptr BER_decode_EC_group(const uint8_t bits[], size_t len); static std::shared_ptr load_EC_group_info(const char* p, const char* a, const char* b, const char* g_x, const char* g_y, const char* order, const OID& oid); // Member data const EC_Group_Data& data() const; std::shared_ptr m_data; }; inline bool operator!=(const EC_Group& lhs, const EC_Group& rhs) { return !(lhs == rhs); } // For compatibility with 1.8 typedef EC_Group EC_Domain_Params; } #endif