Coverage Report

Created: 2024-11-29 06:10

/src/botan/src/lib/pubkey/ec_group/ec_apoint.cpp
Line
Count
Source (jump to first uncovered line)
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
13
namespace Botan {
14
15
34.6k
EC_AffinePoint::EC_AffinePoint(std::unique_ptr<EC_AffinePoint_Data> point) : m_point(std::move(point)) {
16
34.6k
   BOTAN_ASSERT_NONNULL(m_point);
17
34.6k
}
18
19
0
EC_AffinePoint::EC_AffinePoint(const EC_AffinePoint& other) : m_point(other.inner().clone()) {}
20
21
24.8k
EC_AffinePoint::EC_AffinePoint(EC_AffinePoint&& other) noexcept : m_point(std::move(other.m_point)) {}
22
23
0
EC_AffinePoint& EC_AffinePoint::operator=(const EC_AffinePoint& other) {
24
0
   if(this != &other) {
25
0
      m_point = other.inner().clone();
26
0
   }
27
0
   return (*this);
28
0
}
29
30
0
EC_AffinePoint& EC_AffinePoint::operator=(EC_AffinePoint&& other) noexcept {
31
0
   m_point.swap(other.m_point);
32
0
   return (*this);
33
0
}
34
35
16.2k
EC_AffinePoint::EC_AffinePoint(const EC_Group& group, std::span<const uint8_t> bytes) {
36
16.2k
   m_point = group._data()->point_deserialize(bytes);
37
16.2k
   if(!m_point) {
38
3.35k
      throw Decoding_Error("Failed to deserialize elliptic curve point");
39
3.35k
   }
40
16.2k
}
41
42
EC_AffinePoint::EC_AffinePoint(const EC_Group& group, const EC_Point& pt) :
43
11.7k
      EC_AffinePoint(group, pt.encode(EC_Point_Format::Uncompressed)) {}
44
45
0
EC_AffinePoint EC_AffinePoint::identity(const EC_Group& group) {
46
0
   const uint8_t id_encoding[1] = {0};
47
0
   return EC_AffinePoint(group, id_encoding);
48
0
}
49
50
0
EC_AffinePoint EC_AffinePoint::generator(const EC_Group& group) {
51
0
   return EC_AffinePoint(group, group.get_base_point());
52
0
}
53
54
3.72k
std::optional<EC_AffinePoint> EC_AffinePoint::from_bigint_xy(const EC_Group& group, const BigInt& x, const BigInt& y) {
55
3.72k
   if(x.is_negative() || x >= group.get_p()) {
56
0
      return {};
57
0
   }
58
3.72k
   if(y.is_negative() || y >= group.get_p()) {
59
1.86k
      return {};
60
1.86k
   }
61
62
1.86k
   const size_t fe_bytes = group.get_p_bytes();
63
1.86k
   std::vector<uint8_t> sec1(1 + 2 * fe_bytes);
64
1.86k
   sec1[0] = 0x04;
65
1.86k
   x.serialize_to(std::span{sec1}.subspan(1, fe_bytes));
66
1.86k
   y.serialize_to(std::span{sec1}.last(fe_bytes));
67
68
1.86k
   return EC_AffinePoint::deserialize(group, sec1);
69
3.72k
}
70
71
173
size_t EC_AffinePoint::field_element_bytes() const {
72
173
   return inner().field_element_bytes();
73
173
}
74
75
173
bool EC_AffinePoint::is_identity() const {
76
173
   return inner().is_identity();
77
173
}
78
79
EC_AffinePoint EC_AffinePoint::hash_to_curve_ro(const EC_Group& group,
80
                                                std::string_view hash_fn,
81
                                                std::span<const uint8_t> input,
82
0
                                                std::span<const uint8_t> domain_sep) {
83
0
   auto pt = group._data()->point_hash_to_curve_ro(hash_fn, input, domain_sep);
84
0
   return EC_AffinePoint(std::move(pt));
85
0
}
86
87
EC_AffinePoint EC_AffinePoint::hash_to_curve_nu(const EC_Group& group,
88
                                                std::string_view hash_fn,
89
                                                std::span<const uint8_t> input,
90
0
                                                std::span<const uint8_t> domain_sep) {
91
0
   auto pt = group._data()->point_hash_to_curve_nu(hash_fn, input, domain_sep);
92
0
   return EC_AffinePoint(std::move(pt));
93
0
}
94
95
72.3k
EC_AffinePoint::~EC_AffinePoint() = default;
96
97
2.03k
std::optional<EC_AffinePoint> EC_AffinePoint::deserialize(const EC_Group& group, std::span<const uint8_t> bytes) {
98
2.03k
   if(auto pt = group._data()->point_deserialize(bytes)) {
99
2.03k
      return EC_AffinePoint(std::move(pt));
100
2.03k
   } else {
101
0
      return {};
102
0
   }
103
2.03k
}
104
105
20.9k
EC_AffinePoint EC_AffinePoint::g_mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws) {
106
20.9k
   auto pt = scalar._inner().group()->point_g_mul(scalar.inner(), rng, ws);
107
20.9k
   return EC_AffinePoint(std::move(pt));
108
20.9k
}
109
110
11.7k
EC_AffinePoint EC_AffinePoint::mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const {
111
11.7k
   return EC_AffinePoint(inner().mul(scalar._inner(), rng, ws));
112
11.7k
}
113
114
std::optional<EC_AffinePoint> EC_AffinePoint::mul_px_qy(const EC_AffinePoint& p,
115
                                                        const EC_Scalar& x,
116
                                                        const EC_AffinePoint& q,
117
                                                        const EC_Scalar& y,
118
0
                                                        RandomNumberGenerator& rng) {
119
0
   auto pt = p._inner().group()->mul_px_qy(p._inner(), x._inner(), q._inner(), y._inner(), rng);
120
0
   if(pt) {
121
0
      return EC_AffinePoint(std::move(pt));
122
0
   } else {
123
0
      return {};
124
0
   }
125
0
}
126
127
0
EC_AffinePoint EC_AffinePoint::add(const EC_AffinePoint& q) const {
128
0
   auto pt = _inner().group()->affine_add(_inner(), q._inner());
129
0
   return EC_AffinePoint(std::move(pt));
130
0
}
131
132
0
EC_AffinePoint EC_AffinePoint::negate() const {
133
0
   auto pt = this->_inner().group()->affine_neg(this->_inner());
134
0
   return EC_AffinePoint(std::move(pt));
135
0
}
136
137
173
void EC_AffinePoint::serialize_x_to(std::span<uint8_t> bytes) const {
138
173
   BOTAN_STATE_CHECK(!this->is_identity());
139
173
   m_point->serialize_x_to(bytes);
140
173
}
141
142
0
void EC_AffinePoint::serialize_y_to(std::span<uint8_t> bytes) const {
143
0
   BOTAN_STATE_CHECK(!this->is_identity());
144
0
   m_point->serialize_y_to(bytes);
145
0
}
146
147
0
void EC_AffinePoint::serialize_xy_to(std::span<uint8_t> bytes) const {
148
0
   BOTAN_STATE_CHECK(!this->is_identity());
149
0
   m_point->serialize_xy_to(bytes);
150
0
}
151
152
0
void EC_AffinePoint::serialize_compressed_to(std::span<uint8_t> bytes) const {
153
0
   BOTAN_STATE_CHECK(!this->is_identity());
154
0
   m_point->serialize_compressed_to(bytes);
155
0
}
156
157
0
void EC_AffinePoint::serialize_uncompressed_to(std::span<uint8_t> bytes) const {
158
0
   BOTAN_STATE_CHECK(!this->is_identity());
159
0
   m_point->serialize_uncompressed_to(bytes);
160
0
}
161
162
35.6k
EC_Point EC_AffinePoint::to_legacy_point() const {
163
35.6k
   return m_point->to_legacy_point();
164
35.6k
}
165
166
0
EC_AffinePoint EC_AffinePoint::_from_inner(std::unique_ptr<EC_AffinePoint_Data> inner) {
167
0
   return EC_AffinePoint(std::move(inner));
168
0
}
169
170
773
const std::shared_ptr<const EC_Group_Data>& EC_AffinePoint::_group() const {
171
773
   return inner().group();
172
773
}
173
174
}  // namespace Botan