Botan 3.6.0
Crypto and TLS for C&
ec_apoint.cpp
Go to the documentation of this file.
1/*
2* (C) 2024 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/ec_apoint.h>
8
9#include <botan/ec_group.h>
10#include <botan/ec_scalar.h>
11#include <botan/internal/ec_inner_data.h>
12
13namespace Botan {
14
15EC_AffinePoint::EC_AffinePoint(std::unique_ptr<EC_AffinePoint_Data> point) : m_point(std::move(point)) {
16 BOTAN_ASSERT_NONNULL(m_point);
17}
18
19EC_AffinePoint::EC_AffinePoint(const EC_AffinePoint& other) : m_point(other.inner().clone()) {}
20
21EC_AffinePoint::EC_AffinePoint(EC_AffinePoint&& other) noexcept : m_point(std::move(other.m_point)) {}
22
24 if(this != &other) {
25 m_point = other.inner().clone();
26 }
27 return (*this);
28}
29
31 m_point.swap(other.m_point);
32 return (*this);
33}
34
35EC_AffinePoint::EC_AffinePoint(const EC_Group& group, std::span<const uint8_t> bytes) {
36 m_point = group._data()->point_deserialize(bytes);
37 if(!m_point) {
38 throw Decoding_Error("Failed to deserialize elliptic curve point");
39 }
40}
41
44
46 const uint8_t id_encoding[1] = {0};
47 return EC_AffinePoint(group, id_encoding);
48}
49
51 return EC_AffinePoint(group, group.get_base_point());
52}
53
54std::optional<EC_AffinePoint> EC_AffinePoint::from_bigint_xy(const EC_Group& group, const BigInt& x, const BigInt& y) {
55 if(x.is_negative() || x >= group.get_p()) {
56 return {};
57 }
58 if(y.is_negative() || y >= group.get_p()) {
59 return {};
60 }
61
62 const size_t fe_bytes = group.get_p_bytes();
63 std::vector<uint8_t> sec1(1 + 2 * fe_bytes);
64 sec1[0] = 0x04;
65 x.serialize_to(std::span{sec1}.subspan(1, fe_bytes));
66 y.serialize_to(std::span{sec1}.last(fe_bytes));
67
68 return EC_AffinePoint::deserialize(group, sec1);
69}
70
72 return inner().field_element_bytes();
73}
74
76 return inner().is_identity();
77}
78
80 std::string_view hash_fn,
81 std::span<const uint8_t> input,
82 std::span<const uint8_t> domain_sep) {
83 auto pt = group._data()->point_hash_to_curve_ro(hash_fn, input, domain_sep);
84 return EC_AffinePoint(std::move(pt));
85}
86
88 std::string_view hash_fn,
89 std::span<const uint8_t> input,
90 std::span<const uint8_t> domain_sep) {
91 auto pt = group._data()->point_hash_to_curve_nu(hash_fn, input, domain_sep);
92 return EC_AffinePoint(std::move(pt));
93}
94
96
97std::optional<EC_AffinePoint> EC_AffinePoint::deserialize(const EC_Group& group, std::span<const uint8_t> bytes) {
98 if(auto pt = group._data()->point_deserialize(bytes)) {
99 return EC_AffinePoint(std::move(pt));
100 } else {
101 return {};
102 }
103}
104
105EC_AffinePoint EC_AffinePoint::g_mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws) {
106 auto pt = scalar._inner().group()->point_g_mul(scalar.inner(), rng, ws);
107 return EC_AffinePoint(std::move(pt));
108}
109
110EC_AffinePoint EC_AffinePoint::mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const {
111 return EC_AffinePoint(inner().mul(scalar._inner(), rng, ws));
112}
113
114void EC_AffinePoint::serialize_x_to(std::span<uint8_t> bytes) const {
116 m_point->serialize_x_to(bytes);
117}
118
119void EC_AffinePoint::serialize_y_to(std::span<uint8_t> bytes) const {
121 m_point->serialize_y_to(bytes);
122}
123
124void EC_AffinePoint::serialize_xy_to(std::span<uint8_t> bytes) const {
126 m_point->serialize_xy_to(bytes);
127}
128
129void EC_AffinePoint::serialize_compressed_to(std::span<uint8_t> bytes) const {
131 m_point->serialize_compressed_to(bytes);
132}
133
134void EC_AffinePoint::serialize_uncompressed_to(std::span<uint8_t> bytes) const {
136 m_point->serialize_uncompressed_to(bytes);
137}
138
140 return m_point->to_legacy_point();
141}
142
143EC_AffinePoint EC_AffinePoint::_from_inner(std::unique_ptr<EC_AffinePoint_Data> inner) {
144 return EC_AffinePoint(std::move(inner));
145}
146
147const std::shared_ptr<const EC_Group_Data>& EC_AffinePoint::_group() const {
148 return inner().group();
149}
150
151} // namespace Botan
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:41
#define BOTAN_ASSERT_NONNULL(ptr)
Definition assert.h:86
void serialize_to(std::span< uint8_t > out) const
Definition bigint.cpp:383
bool is_negative() const
Definition bigint.h:560
virtual std::unique_ptr< EC_AffinePoint_Data > clone() const =0
virtual size_t field_element_bytes() const =0
virtual const std::shared_ptr< const EC_Group_Data > & group() const =0
virtual bool is_identity() const =0
static EC_AffinePoint hash_to_curve_ro(const EC_Group &group, std::string_view hash_fn, std::span< const uint8_t > input, std::span< const uint8_t > domain_sep)
Definition ec_apoint.cpp:79
size_t field_element_bytes() const
Definition ec_apoint.cpp:71
void serialize_xy_to(std::span< uint8_t > bytes) const
static EC_AffinePoint hash_to_curve_nu(const EC_Group &group, std::string_view hash_fn, std::span< const uint8_t > input, std::span< const uint8_t > domain_sep)
Definition ec_apoint.cpp:87
bool is_identity() const
Return true if this point is the identity element.
Definition ec_apoint.cpp:75
static EC_AffinePoint identity(const EC_Group &group)
Return the identity element.
Definition ec_apoint.cpp:45
static std::optional< EC_AffinePoint > from_bigint_xy(const EC_Group &group, const BigInt &x, const BigInt &y)
Definition ec_apoint.cpp:54
EC_AffinePoint(const EC_Group &group, std::span< const uint8_t > bytes)
Definition ec_apoint.cpp:35
static EC_AffinePoint _from_inner(std::unique_ptr< EC_AffinePoint_Data > inner)
const std::shared_ptr< const EC_Group_Data > & _group() const
static std::optional< EC_AffinePoint > deserialize(const EC_Group &group, std::span< const uint8_t > bytes)
Definition ec_apoint.cpp:97
void serialize_x_to(std::span< uint8_t > bytes) const
void serialize_compressed_to(std::span< uint8_t > bytes) const
void serialize_uncompressed_to(std::span< uint8_t > bytes) const
void serialize_y_to(std::span< uint8_t > bytes) const
EC_Point to_legacy_point() const
EC_AffinePoint & operator=(const EC_AffinePoint &other)
Definition ec_apoint.cpp:23
static EC_AffinePoint g_mul(const EC_Scalar &scalar, RandomNumberGenerator &rng, std::vector< BigInt > &ws)
static EC_AffinePoint generator(const EC_Group &group)
Return the standard group generator.
Definition ec_apoint.cpp:50
EC_AffinePoint mul(const EC_Scalar &scalar, RandomNumberGenerator &rng, std::vector< BigInt > &ws) const
const BigInt & get_p() const
Definition ec_group.cpp:434
const EC_Point & get_base_point() const
Definition ec_group.cpp:446
const std::shared_ptr< EC_Group_Data > & _data() const
Definition ec_group.h:370
size_t get_p_bytes() const
Definition ec_group.cpp:422
virtual const std::shared_ptr< const EC_Group_Data > & group() const =0
const EC_Scalar_Data & _inner() const
Definition ec_scalar.h:211
EC_Point_Format
Definition ec_point.h:19