• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 13215274653

08 Feb 2025 11:38AM UTC coverage: 91.655% (-0.009%) from 91.664%
13215274653

Pull #4650

github

web-flow
Merge 107f31833 into bc555cd3c
Pull Request #4650: Reorganize code and reduce header dependencies

94836 of 103471 relevant lines covered (91.65%)

11230958.94 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.14
/src/lib/pubkey/ec_group/ec_apoint.h
1
/*
2
* (C) 2024 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6

7
#ifndef BOTAN_EC_APOINT_H_
8
#define BOTAN_EC_APOINT_H_
9

10
#include <botan/concepts.h>
11
#include <botan/ec_point_format.h>
12
#include <botan/secmem.h>
13
#include <botan/types.h>
14
#include <memory>
15
#include <optional>
16
#include <span>
17
#include <string_view>
18
#include <vector>
19

20
namespace Botan {
21

22
class BigInt;
23
class RandomNumberGenerator;
24
class EC_Group;
25
class EC_Scalar;
26

27
#if defined(BOTAN_HAS_LEGACY_EC_POINT)
28
class EC_Point;
29
#endif
30

31
class EC_Group_Data;
32
class EC_AffinePoint_Data;
33

34
/// Elliptic Curve Point in Affine Representation
35
///
36
class BOTAN_UNSTABLE_API EC_AffinePoint final {
37
   public:
38
      /// Point deserialization. Throws if wrong length or not a valid point
39
      ///
40
      /// This accepts SEC1 compressed or uncompressed formats
41
      EC_AffinePoint(const EC_Group& group, std::span<const uint8_t> bytes);
42

43
      /// Point deserialization. Returns nullopt if wrong length or not a valid point
44
      ///
45
      /// This accepts SEC1 compressed or uncompressed formats
46
      static std::optional<EC_AffinePoint> deserialize(const EC_Group& group, std::span<const uint8_t> bytes);
47

48
      /// Create a point from a pair (x,y) of integers
49
      ///
50
      /// The integers must be within the field - in the range [0,p) and must
51
      /// satisfy the curve equation
52
      static std::optional<EC_AffinePoint> from_bigint_xy(const EC_Group& group, const BigInt& x, const BigInt& y);
53

54
      /// Multiply by the group generator returning a complete point
55
      ///
56
      /// Workspace argument is transitional
57
      static EC_AffinePoint g_mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws);
58

59
      /// Return the identity element
60
      static EC_AffinePoint identity(const EC_Group& group);
61

62
      /// Return the standard group generator
63
      static EC_AffinePoint generator(const EC_Group& group);
64

65
      /// Hash to curve (RFC 9380), random oracle variant
66
      ///
67
      /// Only supported for specific groups
68
      static EC_AffinePoint hash_to_curve_ro(const EC_Group& group,
69
                                             std::string_view hash_fn,
70
                                             std::span<const uint8_t> input,
71
                                             std::span<const uint8_t> domain_sep);
72

73
      /// Hash to curve (RFC 9380), non uniform variant
74
      ///
75
      /// Only supported for specific groups
76
      static EC_AffinePoint hash_to_curve_nu(const EC_Group& group,
77
                                             std::string_view hash_fn,
78
                                             std::span<const uint8_t> input,
79
                                             std::span<const uint8_t> domain_sep);
80

81
      /// Multiply a point by a scalar returning a complete point
82
      ///
83
      /// Workspace argument is transitional
84
      EC_AffinePoint mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const;
85

86
      /// Multiply a point by a scalar, returning the byte encoding of the x coordinate only
87
      ///
88
      /// Workspace argument is transitional
89
      secure_vector<uint8_t> mul_x_only(const EC_Scalar& scalar,
90
                                        RandomNumberGenerator& rng,
91
                                        std::vector<BigInt>& ws) const;
92

93
      /// Compute 2-ary multiscalar multiplication - p*x + q*y
94
      ///
95
      /// This operation runs in constant time with respect to p, x, q, and y
96
      ///
97
      /// @returns p*x+q*y, or nullopt if the result was the point at infinity
98
      static std::optional<EC_AffinePoint> mul_px_qy(const EC_AffinePoint& p,
99
                                                     const EC_Scalar& x,
100
                                                     const EC_AffinePoint& q,
101
                                                     const EC_Scalar& y,
102
                                                     RandomNumberGenerator& rng);
103

104
      /// Point addition
105
      ///
106
      /// Note that this is quite slow since it converts the resulting
107
      /// projective point immediately to affine coordinates, which requires a
108
      /// field inversion. This can be sufficient when implementing protocols
109
      /// that just need to perform a few additions.
110
      ///
111
      /// In the future a cooresponding EC_ProjectivePoint type may be added
112
      /// which would avoid the expensive affine conversions
113
      EC_AffinePoint add(const EC_AffinePoint& q) const;
114

115
      /// Point negation
116
      EC_AffinePoint negate() const;
117

118
      /// Return the number of bytes of a field element
119
      ///
120
      /// A point consists of two field elements, plus possibly a header
121
      size_t field_element_bytes() const;
122

123
      /// Return true if this point is the identity element
124
      bool is_identity() const;
125

126
      /// Write the fixed length encoding of affine x coordinate
127
      ///
128
      /// The output span must be exactly field_element_bytes long
129
      ///
130
      /// This function will fail if this point is the identity element
131
      void serialize_x_to(std::span<uint8_t> bytes) const;
132

133
      /// Write the fixed length encoding of affine y coordinate
134
      ///
135
      /// The output span must be exactly field_element_bytes long
136
      ///
137
      /// This function will fail if this point is the identity element
138
      void serialize_y_to(std::span<uint8_t> bytes) const;
139

140
      /// Write the fixed length encoding of affine x and y coordinates
141
      ///
142
      /// The output span must be exactly 2*field_element_bytes long
143
      ///
144
      /// This function will fail if this point is the identity element
145
      void serialize_xy_to(std::span<uint8_t> bytes) const;
146

147
      /// Write the fixed length SEC1 compressed encoding
148
      ///
149
      /// The output span must be exactly 1 + field_element_bytes long
150
      ///
151
      /// This function will fail if this point is the identity element
152
      void serialize_compressed_to(std::span<uint8_t> bytes) const;
153

154
      /// Return the fixed length encoding of SEC1 uncompressed encoding
155
      ///
156
      /// The output span must be exactly 1 + 2*field_element_bytes long
157
      ///
158
      /// This function will fail if this point is the identity element
159
      void serialize_uncompressed_to(std::span<uint8_t> bytes) const;
160

161
      /// Return the bytes of the affine x coordinate in a container
162
      ///
163
      /// This function will fail if this point is the identity element
164
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
165
      T x_bytes() const {
605✔
166
         T bytes(this->field_element_bytes());
605✔
167
         this->serialize_x_to(bytes);
605✔
168
         return bytes;
605✔
169
      }
×
170

171
      /// Return the bytes of the affine y coordinate in a container
172
      ///
173
      /// This function will fail if this point is the identity element
174
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
175
      T y_bytes() const {
67✔
176
         T bytes(this->field_element_bytes());
67✔
177
         this->serialize_y_to(bytes);
67✔
178
         return bytes;
67✔
179
      }
×
180

181
      /// Return the bytes of the affine x and y coordinates in a container
182
      ///
183
      /// This function will fail if this point is the identity element
184
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
185
      T xy_bytes() const {
234✔
186
         T bytes(2 * this->field_element_bytes());
234✔
187
         this->serialize_xy_to(bytes);
234✔
188
         return bytes;
234✔
189
      }
×
190

191
      /// Return the bytes of the affine x and y coordinates in a container
192
      ///
193
      /// This function will fail if this point is the identity element
194
      template <concepts::resizable_byte_buffer T = std::vector<uint8_t>>
195
      T serialize_uncompressed() const {
30,282✔
196
         T bytes(1 + 2 * this->field_element_bytes());
30,282✔
197
         this->serialize_uncompressed_to(bytes);
30,282✔
198
         return bytes;
30,282✔
199
      }
×
200

201
      /// Return the bytes of the affine x and y coordinates in a container
202
      ///
203
      /// This function will fail if this point is the identity element
204
      template <concepts::resizable_byte_buffer T = std::vector<uint8_t>>
205
      T serialize_compressed() const {
11,986✔
206
         T bytes(1 + this->field_element_bytes());
11,986✔
207
         this->serialize_compressed_to(bytes);
11,986✔
208
         return bytes;
11,986✔
209
      }
×
210

211
      bool operator==(const EC_AffinePoint& other) const;
212

213
      bool operator!=(const EC_AffinePoint& other) const { return !(*this == other); }
1,052✔
214

215
      /// Return an encoding depending on the requested format
216
      std::vector<uint8_t> serialize(EC_Point_Format format) const;
217

218
      EC_AffinePoint(const EC_AffinePoint& other);
219
      EC_AffinePoint(EC_AffinePoint&& other) noexcept;
220

221
      EC_AffinePoint& operator=(const EC_AffinePoint& other);
222
      EC_AffinePoint& operator=(EC_AffinePoint&& other) noexcept;
223

224
#if defined(BOTAN_HAS_LEGACY_EC_POINT)
225
      /**
226
      * Deprecated conversion
227
      */
228
      EC_AffinePoint(const EC_Group& group, const EC_Point& pt);
229

230
      /**
231
      * Deprecated conversion
232
      */
233
      EC_Point to_legacy_point() const;
234
#endif
235

236
      ~EC_AffinePoint();
237

238
      const EC_AffinePoint_Data& _inner() const { return inner(); }
54,722✔
239

240
      static EC_AffinePoint _from_inner(std::unique_ptr<EC_AffinePoint_Data> inner);
241

242
      const std::shared_ptr<const EC_Group_Data>& _group() const;
243

244
   private:
245
      friend class EC_Mul2Table;
246

247
      EC_AffinePoint(std::unique_ptr<EC_AffinePoint_Data> point);
248

249
      const EC_AffinePoint_Data& inner() const { return *m_point; }
171,659✔
250

251
      std::unique_ptr<EC_AffinePoint_Data> m_point;
252
};
253

254
}  // namespace Botan
255

256
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc