Skip to content

Commit

Permalink
Move some of EC_Group_Data to its own source file
Browse files Browse the repository at this point in the history
  • Loading branch information
randombit committed May 23, 2024
1 parent b594b6b commit 6afd45b
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 92 deletions.
152 changes: 152 additions & 0 deletions src/lib/pubkey/ec_group/ec_inner_data.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* (C) 2024 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include <botan/internal/ec_inner_data.h>

namespace Botan {

EC_Group_Data::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) :
m_curve(p, a, b),
m_base_point(m_curve, g_x, g_y),
m_g_x(g_x),
m_g_y(g_y),
m_order(order),
m_cofactor(cofactor),
m_mod_order(order),
m_base_mult(m_base_point, m_mod_order),
m_oid(oid),
m_p_bits(p.bits()),
m_order_bits(order.bits()),
m_order_bytes((m_order_bits + 7) / 8),
m_a_is_minus_3(a == p - 3),
m_a_is_zero(a.is_zero()),
m_source(source) {}

bool EC_Group_Data::params_match(const BigInt& p,
const BigInt& a,
const BigInt& b,
const BigInt& g_x,
const BigInt& g_y,
const BigInt& order,
const BigInt& cofactor) const {
return (this->p() == p && this->a() == a && this->b() == b && this->order() == order &&
this->cofactor() == cofactor && this->g_x() == g_x && this->g_y() == g_y);
}

bool EC_Group_Data::params_match(const EC_Group_Data& other) const {
return params_match(other.p(), other.a(), other.b(), other.g_x(), other.g_y(), other.order(), other.cofactor());
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_from_bytes_with_trunc(std::span<const uint8_t> bytes) const {
auto bn = BigInt::from_bytes_with_max_bits(bytes.data(), bytes.size(), m_order_bits);
return std::make_unique<EC_Scalar_Data>(mod_order(bn));
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_from_bytes_mod_order(std::span<const uint8_t> bytes) const {
return std::make_unique<EC_Scalar_Data>(mod_order(BigInt(bytes)));
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_random(RandomNumberGenerator& rng) const {
return std::make_unique<EC_Scalar_Data>(BigInt::random_integer(rng, BigInt::one(), m_order));
}

bool EC_Group_Data::scalar_is_zero(const EC_Scalar_Data& s) const {
return s.value().is_zero();
}

bool EC_Group_Data::scalar_is_eq(const EC_Scalar_Data& x, const EC_Scalar_Data& y) const {
return x.value() == y.value();
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_zero() const {
return std::make_unique<EC_Scalar_Data>(BigInt::zero());
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_one() const {
return std::make_unique<EC_Scalar_Data>(BigInt::one());
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_invert(const EC_Scalar_Data& s) const {
return std::make_unique<EC_Scalar_Data>(inverse_mod_order(s.value()));
}

void EC_Group_Data::scalar_assign(EC_Scalar_Data& x, const EC_Scalar_Data& y) {
x.set_value(y.value());
}

void EC_Group_Data::scalar_square_self(EC_Scalar_Data& s) {

Check warning on line 88 in src/lib/pubkey/ec_group/ec_inner_data.cpp

View workflow job for this annotation

GitHub Actions / Clang Tidy

method 'scalar_square_self' can be made const
s.set_value(square_mod_order(s.value()));
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_negate(const EC_Scalar_Data& s) const {
return std::make_unique<EC_Scalar_Data>(mod_order(-s.value()));
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_add(const EC_Scalar_Data& a, const EC_Scalar_Data& b) const {
return std::make_unique<EC_Scalar_Data>(mod_order(a.value() + b.value()));
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_sub(const EC_Scalar_Data& a, const EC_Scalar_Data& b) const {
return std::make_unique<EC_Scalar_Data>(mod_order(a.value() - b.value()));
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_mul(const EC_Scalar_Data& a, const EC_Scalar_Data& b) const {
return std::make_unique<EC_Scalar_Data>(multiply_mod_order(a.value(), b.value()));
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_from_bigint(const BigInt& bn) const {
// Assumed to have been already checked as in range
return std::make_unique<EC_Scalar_Data>(bn);
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::gk_x_mod_order(const EC_Scalar_Data& scalar,
RandomNumberGenerator& rng,
std::vector<BigInt>& ws) const {
const auto pt = m_base_mult.mul(scalar.value(), rng, m_order, ws);

if(pt.is_zero()) {
return scalar_zero();
} else {
return std::make_unique<EC_Scalar_Data>(mod_order(pt.get_affine_x()));
}
}

std::unique_ptr<EC_Scalar_Data> EC_Group_Data::scalar_deserialize(std::span<const uint8_t> bytes) {
if(bytes.size() != m_order_bytes) {
return nullptr;
}

BigInt r(bytes.data(), bytes.size());

if(r.is_zero() || r >= m_order) {
return nullptr;
}

return std::make_unique<EC_Scalar_Data>(std::move(r));
}

std::vector<uint8_t> EC_Group_Data::scalar_serialize(const EC_Scalar_Data& s) const {
std::vector<uint8_t> bytes(m_order_bytes);
s.value().binary_encode(bytes.data(), m_order_bytes);
return bytes;
}

std::vector<uint8_t> EC_Group_Data::scalar_serialize_pair(const EC_Scalar_Data& r, const EC_Scalar_Data& s) const {
std::vector<uint8_t> bytes(2 * m_order_bytes);
r.value().binary_encode(bytes.data(), m_order_bytes);
s.value().binary_encode(bytes.data() + m_order_bytes, m_order_bytes);
return bytes;
}

} // namespace Botan
114 changes: 22 additions & 92 deletions src/lib/pubkey/ec_group/ec_inner_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,38 +71,17 @@ class EC_Group_Data final {
const BigInt& order,
const BigInt& cofactor,
const OID& oid,
EC_Group_Source source) :
m_curve(p, a, b),
m_base_point(m_curve, g_x, g_y),
m_g_x(g_x),
m_g_y(g_y),
m_order(order),
m_cofactor(cofactor),
m_mod_order(order),
m_base_mult(m_base_point, m_mod_order),
m_oid(oid),
m_p_bits(p.bits()),
m_order_bits(order.bits()),
m_order_bytes((m_order_bits + 7) / 8),
m_a_is_minus_3(a == p - 3),
m_a_is_zero(a.is_zero()),
m_source(source) {}
EC_Group_Source source);

bool params_match(const BigInt& p,
const BigInt& a,
const BigInt& b,
const BigInt& g_x,
const BigInt& g_y,
const BigInt& order,
const BigInt& cofactor) const {
return (this->p() == p && this->a() == a && this->b() == b && this->order() == order &&
this->cofactor() == cofactor && this->g_x() == g_x && this->g_y() == g_y);
}
const BigInt& cofactor) const;

bool params_match(const EC_Group_Data& other) const {
return params_match(
other.p(), other.a(), other.b(), other.g_x(), other.g_y(), other.order(), other.cofactor());
}
bool params_match(const EC_Group_Data& other) const;

void set_oid(const OID& oid) {
BOTAN_STATE_CHECK(m_oid.empty());
Expand Down Expand Up @@ -159,94 +138,45 @@ class EC_Group_Data final {

EC_Group_Source source() const { return m_source; }

std::unique_ptr<EC_Scalar_Data> scalar_from_bytes_with_trunc(std::span<const uint8_t> bytes) const {
auto bn = BigInt::from_bytes_with_max_bits(bytes.data(), bytes.size(), m_order_bits);
return std::make_unique<EC_Scalar_Data>(mod_order(bn));
}
std::unique_ptr<EC_Scalar_Data> scalar_from_bytes_with_trunc(std::span<const uint8_t> bytes) const;

std::unique_ptr<EC_Scalar_Data> scalar_from_bytes_mod_order(std::span<const uint8_t> bytes) const {
return std::make_unique<EC_Scalar_Data>(mod_order(BigInt(bytes)));
}
std::unique_ptr<EC_Scalar_Data> scalar_from_bytes_mod_order(std::span<const uint8_t> bytes) const;

std::unique_ptr<EC_Scalar_Data> scalar_random(RandomNumberGenerator& rng) const {
return std::make_unique<EC_Scalar_Data>(BigInt::random_integer(rng, BigInt::one(), m_order));
}
std::unique_ptr<EC_Scalar_Data> scalar_random(RandomNumberGenerator& rng) const;

bool scalar_is_zero(const EC_Scalar_Data& s) const { return s.value().is_zero(); }
bool scalar_is_zero(const EC_Scalar_Data& s) const;

bool scalar_is_eq(const EC_Scalar_Data& x, const EC_Scalar_Data& y) const { return x.value() == y.value(); }
bool scalar_is_eq(const EC_Scalar_Data& x, const EC_Scalar_Data& y) const;

std::unique_ptr<EC_Scalar_Data> scalar_zero() const { return std::make_unique<EC_Scalar_Data>(BigInt::zero()); }
std::unique_ptr<EC_Scalar_Data> scalar_zero() const;

std::unique_ptr<EC_Scalar_Data> scalar_one() const { return std::make_unique<EC_Scalar_Data>(BigInt::one()); }
std::unique_ptr<EC_Scalar_Data> scalar_one() const;

std::unique_ptr<EC_Scalar_Data> scalar_invert(const EC_Scalar_Data& s) const {
return std::make_unique<EC_Scalar_Data>(inverse_mod_order(s.value()));
}
std::unique_ptr<EC_Scalar_Data> scalar_invert(const EC_Scalar_Data& s) const;

void scalar_assign(EC_Scalar_Data& x, const EC_Scalar_Data& y) { x.set_value(y.value()); }
void scalar_assign(EC_Scalar_Data& x, const EC_Scalar_Data& y);

void scalar_square_self(EC_Scalar_Data& s) { s.set_value(square_mod_order(s.value())); }
void scalar_square_self(EC_Scalar_Data& s);

std::unique_ptr<EC_Scalar_Data> scalar_negate(const EC_Scalar_Data& s) const {
return std::make_unique<EC_Scalar_Data>(mod_order(-s.value()));
}
std::unique_ptr<EC_Scalar_Data> scalar_negate(const EC_Scalar_Data& s) const;

std::unique_ptr<EC_Scalar_Data> scalar_add(const EC_Scalar_Data& a, const EC_Scalar_Data& b) const {
return std::make_unique<EC_Scalar_Data>(mod_order(a.value() + b.value()));
}
std::unique_ptr<EC_Scalar_Data> scalar_add(const EC_Scalar_Data& a, const EC_Scalar_Data& b) const;

std::unique_ptr<EC_Scalar_Data> scalar_sub(const EC_Scalar_Data& a, const EC_Scalar_Data& b) const {
return std::make_unique<EC_Scalar_Data>(mod_order(a.value() - b.value()));
}
std::unique_ptr<EC_Scalar_Data> scalar_sub(const EC_Scalar_Data& a, const EC_Scalar_Data& b) const;

std::unique_ptr<EC_Scalar_Data> scalar_mul(const EC_Scalar_Data& a, const EC_Scalar_Data& b) const {
return std::make_unique<EC_Scalar_Data>(multiply_mod_order(a.value(), b.value()));
}
std::unique_ptr<EC_Scalar_Data> scalar_mul(const EC_Scalar_Data& a, const EC_Scalar_Data& b) const;

std::unique_ptr<EC_Scalar_Data> scalar_from_bigint(const BigInt& bn) const {
// Assumed to have been already checked as in range
return std::make_unique<EC_Scalar_Data>(bn);
}
std::unique_ptr<EC_Scalar_Data> scalar_from_bigint(const BigInt& bn) const;

std::unique_ptr<EC_Scalar_Data> gk_x_mod_order(const EC_Scalar_Data& scalar,
RandomNumberGenerator& rng,
std::vector<BigInt>& ws) const {
const auto pt = m_base_mult.mul(scalar.value(), rng, m_order, ws);

if(pt.is_zero()) {
return scalar_zero();
} else {
return std::make_unique<EC_Scalar_Data>(mod_order(pt.get_affine_x()));
}
}
std::vector<BigInt>& ws) const;

std::unique_ptr<EC_Scalar_Data> scalar_deserialize(std::span<const uint8_t> bytes) {
if(bytes.size() != m_order_bytes) {
return nullptr;
}
std::unique_ptr<EC_Scalar_Data> scalar_deserialize(std::span<const uint8_t> bytes);

BigInt r(bytes.data(), bytes.size());
std::vector<uint8_t> scalar_serialize(const EC_Scalar_Data& s) const;

if(r.is_zero() || r >= m_order) {
return nullptr;
}

return std::make_unique<EC_Scalar_Data>(std::move(r));
}

std::vector<uint8_t> scalar_serialize(const EC_Scalar_Data& s) const {
std::vector<uint8_t> bytes(m_order_bytes);
s.value().binary_encode(bytes.data(), m_order_bytes);
return bytes;
}

std::vector<uint8_t> scalar_serialize_pair(const EC_Scalar_Data& r, const EC_Scalar_Data& s) const {
std::vector<uint8_t> bytes(2 * m_order_bytes);
r.value().binary_encode(bytes.data(), m_order_bytes);
s.value().binary_encode(bytes.data() + m_order_bytes, m_order_bytes);
return bytes;
}
std::vector<uint8_t> scalar_serialize_pair(const EC_Scalar_Data& r, const EC_Scalar_Data& s) const;

private:
CurveGFp m_curve;
Expand Down

0 comments on commit 6afd45b

Please sign in to comment.