7#include <botan/internal/ec_inner_data.h>
9#include <botan/der_enc.h>
10#include <botan/internal/ec_inner_bn.h>
11#include <botan/internal/ec_inner_pc.h>
12#include <botan/internal/pcurves.h>
13#include <botan/internal/point_mul.h>
29 m_base_point(m_curve, g_x, g_y),
37 m_order_bits(order.bits()),
38 m_order_bytes((m_order_bits + 7) / 8),
39 m_a_is_minus_3(a == p - 3),
40 m_a_is_zero(a.is_zero()),
41 m_has_cofactor(m_cofactor != 1),
42 m_order_is_less_than_p(m_order < p),
45 DER_Encoder der(m_der_named_curve);
48 if(const auto id = PCurve::PrimeOrderCurveId::from_oid(m_oid)) {
49 m_pcurve = PCurve::PrimeOrderCurve::from_id(*id);
56 m_base_mult = std::make_unique<EC_Point_Base_Point_Precompute>(m_base_point, m_mod_order);
60bool EC_Group_Data::params_match(
const BigInt& p,
66 const BigInt& cofactor)
const {
67 return (this->p() == p && this->a() == a && this->b() ==
b && this->order() == order &&
68 this->cofactor() == cofactor && this->g_x() == g_x && this->g_y() == g_y);
72 return params_match(other.
p(), other.
a(), other.
b(), other.
g_x(), other.
g_y(), other.
order(), other.
cofactor());
75void EC_Group_Data::set_oid(
const OID& oid) {
84std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_from_bytes_with_trunc(std::span<const uint8_t> bytes)
const {
85 const size_t bit_length = 8 * bytes.size();
87 if(bit_length < order_bits()) {
89 return this->scalar_from_bytes_mod_order(bytes);
91 const size_t shift = bit_length - order_bits();
93 const size_t new_length = bytes.size() - (shift / 8);
94 const size_t bit_shift = shift % 8;
98 return this->scalar_from_bytes_mod_order(bytes.first(new_length));
100 std::vector<uint8_t> sbytes(new_length);
103 for(
size_t i = 0; i != new_length; ++i) {
104 const uint8_t w = bytes[i];
105 sbytes[i] = (w >> bit_shift) |
carry;
106 carry = w << (8 - bit_shift);
109 return this->scalar_from_bytes_mod_order(sbytes);
114std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_from_bytes_mod_order(std::span<const uint8_t> bytes)
const {
115 if(bytes.size() >= 2 * order_bytes()) {
120 if(
auto s = m_pcurve->scalar_from_wide_bytes(bytes)) {
121 return std::make_unique<EC_Scalar_Data_PC>(shared_from_this(), std::move(*s));
126 return std::make_unique<EC_Scalar_Data_BN>(shared_from_this(), mod_order(
BigInt(bytes)));
132 return std::make_unique<EC_Scalar_Data_PC>(shared_from_this(), m_pcurve->random_scalar(rng));
134 return std::make_unique<EC_Scalar_Data_BN>(shared_from_this(),
135 BigInt::random_integer(rng, BigInt::one(), m_order));
139std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_zero()
const {
141 return std::make_unique<EC_Scalar_Data_PC>(shared_from_this(), m_pcurve->scalar_zero());
143 return std::make_unique<EC_Scalar_Data_BN>(shared_from_this(), BigInt::zero());
147std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_one()
const {
149 return std::make_unique<EC_Scalar_Data_PC>(shared_from_this(), m_pcurve->scalar_one());
151 return std::make_unique<EC_Scalar_Data_BN>(shared_from_this(), BigInt::one());
155std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_from_bigint(
const BigInt& bn)
const {
156 if(bn <= 0 || bn >= m_order) {
161 return this->scalar_deserialize(bn.
serialize(m_order_bytes));
163 return std::make_unique<EC_Scalar_Data_BN>(shared_from_this(), bn);
167std::unique_ptr<EC_Scalar_Data> EC_Group_Data::gk_x_mod_order(
const EC_Scalar_Data& scalar,
169 std::vector<BigInt>& ws)
const {
171 const auto& k = EC_Scalar_Data_PC::checked_ref(scalar);
172 auto gk_x_mod_order = m_pcurve->base_point_mul_x_mod_order(k.value(), rng);
173 return std::make_unique<EC_Scalar_Data_PC>(shared_from_this(), gk_x_mod_order);
175 const auto& k = EC_Scalar_Data_BN::checked_ref(scalar);
177 const auto pt = m_base_mult->mul(k.value(), rng, m_order, ws);
180 return scalar_zero();
182 return std::make_unique<EC_Scalar_Data_BN>(shared_from_this(), mod_order(pt.get_affine_x()));
187std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_deserialize(std::span<const uint8_t> bytes)
const {
188 if(bytes.size() != m_order_bytes) {
193 if(
auto s = m_pcurve->deserialize_scalar(bytes)) {
194 return std::make_unique<EC_Scalar_Data_PC>(shared_from_this(), *s);
201 if(r.
is_zero() || r >= m_order) {
205 return std::make_unique<EC_Scalar_Data_BN>(shared_from_this(), std::move(r));
209std::unique_ptr<EC_AffinePoint_Data> EC_Group_Data::point_deserialize(std::span<const uint8_t> bytes)
const {
212 if(
auto pt = m_pcurve->deserialize_point(bytes)) {
213 return std::make_unique<EC_AffinePoint_Data_PC>(shared_from_this(), std::move(*pt));
218 auto pt =
Botan::OS2ECP(bytes.data(), bytes.size(), curve());
219 return std::make_unique<EC_AffinePoint_Data_BN>(shared_from_this(), std::move(pt));
226std::unique_ptr<EC_AffinePoint_Data> EC_Group_Data::point_hash_to_curve_ro(std::string_view hash_fn,
227 std::span<const uint8_t> input,
228 std::span<const uint8_t> domain_sep)
const {
230 auto pt = m_pcurve->hash_to_curve_ro(hash_fn, input, domain_sep);
231 return std::make_unique<EC_AffinePoint_Data_PC>(shared_from_this(), pt.to_affine());
233 throw Not_Implemented(
"Hash to curve is not implemented for this curve");
237std::unique_ptr<EC_AffinePoint_Data> EC_Group_Data::point_hash_to_curve_nu(std::string_view hash_fn,
238 std::span<const uint8_t> input,
239 std::span<const uint8_t> domain_sep)
const {
241 auto pt = m_pcurve->hash_to_curve_nu(hash_fn, input, domain_sep);
242 return std::make_unique<EC_AffinePoint_Data_PC>(shared_from_this(), std::move(pt));
244 throw Not_Implemented(
"Hash to curve is not implemented for this curve");
248std::unique_ptr<EC_AffinePoint_Data> EC_Group_Data::point_g_mul(
const EC_Scalar_Data& scalar,
250 std::vector<BigInt>& ws)
const {
252 const auto& k = EC_Scalar_Data_PC::checked_ref(scalar);
253 auto pt = m_pcurve->mul_by_g(k.value(), rng).to_affine();
254 return std::make_unique<EC_AffinePoint_Data_PC>(shared_from_this(), std::move(pt));
256 const auto& group = scalar.
group();
257 const auto& bn = EC_Scalar_Data_BN::checked_ref(scalar);
260 auto pt = group->m_base_mult->mul(bn.value(), rng, m_order, ws);
261 return std::make_unique<EC_AffinePoint_Data_BN>(shared_from_this(), std::move(pt));
268 return std::make_unique<EC_Mul2Table_Data_PC>(g, h);
271 return std::make_unique<EC_Mul2Table_Data_BN>(g, h);
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ARG_CHECK(expr, msg)
T serialize(size_t len) const
DER_Encoder & encode(bool b)
const BigInt & g_x() const
EC_Group_Data(const BigInt &p, const BigInt &a, const BigInt &b, const BigInt &g_x, const BigInt &g_y, const BigInt &order, const BigInt &cofactor, const OID &oid, EC_Group_Source source)
const BigInt & cofactor() const
const BigInt & g_y() const
const BigInt & order() const
virtual const std::shared_ptr< const EC_Group_Data > & group() const =0
EC_Point OS2ECP(const uint8_t data[], size_t data_len, const CurveGFp &curve)
void carry(int64_t &h0, int64_t &h1)