7#include <botan/internal/ec_inner_pc.h>
13PCurve::PrimeOrderCurve::AffinePoint deserialize_pcurve_pt(
const PCurve::PrimeOrderCurve& curve,
14 std::span<const uint8_t> bytes) {
15 if(
auto pt = curve.deserialize_point(bytes)) {
18 throw Decoding_Error(
"Invalid elliptic curve point encoding");
27 throw Invalid_State(
"Failed conversion to EC_Scalar_Data_PC");
37 return this->
group()->order_bytes();
41 return std::make_unique<EC_Scalar_Data_PC>(this->
group(), this->
value());
45 return this->
value().is_zero();
62 return std::make_unique<EC_Scalar_Data_PC>(m_group, m_v.
negate());
66 return std::make_unique<EC_Scalar_Data_PC>(m_group, m_v.
invert());
70 return std::make_unique<EC_Scalar_Data_PC>(m_group, m_v.
invert_vartime());
74 return std::make_unique<EC_Scalar_Data_PC>(m_group, m_v +
checked_ref(other).
value());
78 return std::make_unique<EC_Scalar_Data_PC>(m_group, m_v -
checked_ref(other).
value());
82 return std::make_unique<EC_Scalar_Data_PC>(m_group, m_v *
checked_ref(other).
value());
87 m_group->pcurve().serialize_scalar(
bytes, m_v);
92 m_group(std::move(group)), m_pt(std::move(pt)) {
94 m_xy = m_pt.serialize<secure_vector<uint8_t>>();
95 BOTAN_ASSERT_NOMSG(m_xy.size() == 1 + 2 * field_element_bytes());
100 std::span<const uint8_t> bytes) :
101 m_group(std::move(group)), m_pt(deserialize_pcurve_pt(m_group->pcurve(), bytes)) {
103 m_xy = m_pt.serialize<secure_vector<uint8_t>>();
104 BOTAN_ASSERT_NOMSG(m_xy.size() == 1 + 2 * field_element_bytes());
111 throw Invalid_State(
"Failed conversion to EC_AffinePoint_Data_PC");
117 return std::make_unique<EC_AffinePoint_Data_PC>(m_group, m_pt);
126 std::vector<BigInt>& ws)
const {
131 auto pt = m_group->pcurve().mul(m_pt, k, rng).to_affine();
132 return std::make_unique<EC_AffinePoint_Data_PC>(m_group, std::move(pt));
137 std::vector<BigInt>& ws)
const {
142 return m_group->pcurve().mul_x_only(m_pt, k, rng);
146 return m_group->pcurve().field_element_bytes();
157 copy_mem(bytes, std::span{m_xy}.subspan(1, fe_bytes));
164 copy_mem(bytes, std::span{m_xy}.subspan(1 + fe_bytes, fe_bytes));
171 copy_mem(bytes, std::span{m_xy}.last(2 * fe_bytes));
178 const bool y_is_odd = (m_xy.back() & 0x01) == 0x01;
181 stuffer.
append(y_is_odd ? 0x03 : 0x02);
188 BOTAN_ARG_CHECK(bytes.size() == 1 + 2 * fe_bytes,
"Invalid output size");
192#if defined(BOTAN_HAS_LEGACY_EC_POINT)
193EC_Point EC_AffinePoint_Data_PC::to_legacy_point()
const {
198 return EC_Point(m_group->curve(),
210 m_tbl = m_group->pcurve().mul2_setup_g(pt_q.value());
220 if(
auto pt = m_group->pcurve().mul2_vartime(*m_tbl, x.value(), y.value())) {
221 return std::make_unique<EC_AffinePoint_Data_PC>(m_group, pt->to_affine());
236 return m_group->pcurve().mul2_vartime_x_mod_order_eq(*m_tbl, v.value(), x.value(), y.value());
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ARG_CHECK(expr, msg)
static BigInt from_bytes(std::span< const uint8_t > bytes)
Helper class to ease in-place marshalling of concatenated fixed-length values.
constexpr void append(std::span< const uint8_t > buffer)
constexpr std::span< uint8_t > next(size_t bytes)
size_t field_element_bytes() const override
void serialize_uncompressed_to(std::span< uint8_t > bytes) const override
void serialize_xy_to(std::span< uint8_t > bytes) const override
std::unique_ptr< EC_AffinePoint_Data > mul(const EC_Scalar_Data &scalar, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const override
std::unique_ptr< EC_AffinePoint_Data > clone() const override
const std::shared_ptr< const EC_Group_Data > & group() const override
EC_AffinePoint_Data_PC(std::shared_ptr< const EC_Group_Data > group, PCurve::PrimeOrderCurve::AffinePoint pt)
bool is_identity() const override
void serialize_x_to(std::span< uint8_t > bytes) const override
void serialize_y_to(std::span< uint8_t > bytes) const override
secure_vector< uint8_t > mul_x_only(const EC_Scalar_Data &scalar, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const override
static const EC_AffinePoint_Data_PC & checked_ref(const EC_AffinePoint_Data &data)
void serialize_compressed_to(std::span< uint8_t > bytes) const override
virtual const std::shared_ptr< const EC_Group_Data > & group() const =0
bool mul2_vartime_x_mod_order_eq(const EC_Scalar_Data &v, const EC_Scalar_Data &x, const EC_Scalar_Data &y) const override
EC_Mul2Table_Data_PC(const EC_AffinePoint_Data &q)
std::unique_ptr< EC_AffinePoint_Data > mul2_vartime(const EC_Scalar_Data &x, const EC_Scalar_Data &y) const override
void serialize_to(std::span< uint8_t > bytes) const override
std::unique_ptr< EC_Scalar_Data > invert() const override
void assign(const EC_Scalar_Data &y) override
size_t bytes() const override
static const EC_Scalar_Data_PC & checked_ref(const EC_Scalar_Data &data)
std::unique_ptr< EC_Scalar_Data > sub(const EC_Scalar_Data &other) const override
bool is_eq(const EC_Scalar_Data &y) const override
void square_self() override
std::unique_ptr< EC_Scalar_Data > clone() const override
std::unique_ptr< EC_Scalar_Data > mul(const EC_Scalar_Data &other) const override
const std::shared_ptr< const EC_Group_Data > & group() const override
std::unique_ptr< EC_Scalar_Data > negate() const override
bool is_zero() const override
std::unique_ptr< EC_Scalar_Data > add(const EC_Scalar_Data &other) const override
std::unique_ptr< EC_Scalar_Data > invert_vartime() const override
const auto & value() const
virtual const std::shared_ptr< const EC_Group_Data > & group() const =0
Scalar invert_vartime() const
std::vector< T, secure_allocator< T > > secure_vector
constexpr void copy_mem(T *out, const T *in, size_t n)