Coverage Report

Created: 2024-11-29 06:10

/src/botan/build/include/public/botan/ec_apoint.h
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
#ifndef BOTAN_EC_APOINT_H_
8
#define BOTAN_EC_APOINT_H_
9
10
#include <botan/concepts.h>
11
#include <botan/secmem.h>
12
#include <botan/types.h>
13
#include <optional>
14
#include <span>
15
#include <string_view>
16
#include <vector>
17
18
namespace Botan {
19
20
class BigInt;
21
class RandomNumberGenerator;
22
class EC_Group;
23
class EC_Scalar;
24
class EC_Point;
25
26
class EC_Group_Data;
27
class EC_AffinePoint_Data;
28
29
/// Elliptic Curve in Affine Representation
30
///
31
class BOTAN_UNSTABLE_API EC_AffinePoint final {
32
   public:
33
      /// Point deserialization. Throws if wrong length or not a valid point
34
      ///
35
      /// This accepts SEC1 compressed or uncompressed formats
36
      EC_AffinePoint(const EC_Group& group, std::span<const uint8_t> bytes);
37
38
      /// Point deserialization. Returns nullopt if wrong length or not a valid point
39
      ///
40
      /// This accepts SEC1 compressed or uncompressed formats
41
      static std::optional<EC_AffinePoint> deserialize(const EC_Group& group, std::span<const uint8_t> bytes);
42
43
      /// Create a point from a pair (x,y) of integers
44
      ///
45
      /// The integers must be within the field - in the range [0,p) and must
46
      /// satisfy the curve equation
47
      static std::optional<EC_AffinePoint> from_bigint_xy(const EC_Group& group, const BigInt& x, const BigInt& y);
48
49
      /// Multiply by the group generator returning a complete point
50
      ///
51
      /// Workspace argument is transitional
52
      static EC_AffinePoint g_mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws);
53
54
      /// Return the identity element
55
      static EC_AffinePoint identity(const EC_Group& group);
56
57
      /// Return the standard group generator
58
      static EC_AffinePoint generator(const EC_Group& group);
59
60
      /// Hash to curve (RFC 9380), random oracle variant
61
      ///
62
      /// Only supported for specific groups
63
      static EC_AffinePoint hash_to_curve_ro(const EC_Group& group,
64
                                             std::string_view hash_fn,
65
                                             std::span<const uint8_t> input,
66
                                             std::span<const uint8_t> domain_sep);
67
68
      /// Hash to curve (RFC 9380), non uniform variant
69
      ///
70
      /// Only supported for specific groups
71
      static EC_AffinePoint hash_to_curve_nu(const EC_Group& group,
72
                                             std::string_view hash_fn,
73
                                             std::span<const uint8_t> input,
74
                                             std::span<const uint8_t> domain_sep);
75
76
      /// Multiply a point by a scalar returning a complete point
77
      ///
78
      /// Workspace argument is transitional
79
      EC_AffinePoint mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const;
80
81
      /// Compute 2-ary multiscalar multiplication - p*x + q*y
82
      ///
83
      /// This operation runs in constant time with respect to p, x, q, and y
84
      ///
85
      /// @returns p*x+q*y, or nullopt if the result was the point at infinity
86
      static std::optional<EC_AffinePoint> mul_px_qy(const EC_AffinePoint& p,
87
                                                     const EC_Scalar& x,
88
                                                     const EC_AffinePoint& q,
89
                                                     const EC_Scalar& y,
90
                                                     RandomNumberGenerator& rng);
91
92
      /// Point addition
93
      ///
94
      /// Note that this is quite slow since it converts the resulting
95
      /// projective point immediately to affine coordinates, which requires a
96
      /// field inversion. This can be sufficient when implementing protocols
97
      /// that just need to perform a few additions.
98
      ///
99
      /// In the future a cooresponding EC_ProjectivePoint type may be added
100
      /// which would avoid the expensive affine conversions
101
      EC_AffinePoint add(const EC_AffinePoint& q) const;
102
103
      /// Point negation
104
      EC_AffinePoint negate() const;
105
106
      /// Return the number of bytes of a field element
107
      ///
108
      /// A point consists of two field elements, plus possibly a header
109
      size_t field_element_bytes() const;
110
111
      /// Return true if this point is the identity element
112
      bool is_identity() const;
113
114
      /// Write the fixed length encoding of affine x coordinate
115
      ///
116
      /// The output span must be exactly field_element_bytes long
117
      ///
118
      /// This function will fail if this point is the identity element
119
      void serialize_x_to(std::span<uint8_t> bytes) const;
120
121
      /// Write the fixed length encoding of affine y coordinate
122
      ///
123
      /// The output span must be exactly field_element_bytes long
124
      ///
125
      /// This function will fail if this point is the identity element
126
      void serialize_y_to(std::span<uint8_t> bytes) const;
127
128
      /// Write the fixed length encoding of affine x and y coordinates
129
      ///
130
      /// The output span must be exactly 2*field_element_bytes long
131
      ///
132
      /// This function will fail if this point is the identity element
133
      void serialize_xy_to(std::span<uint8_t> bytes) const;
134
135
      /// Write the fixed length SEC1 compressed encoding
136
      ///
137
      /// The output span must be exactly 1 + field_element_bytes long
138
      ///
139
      /// This function will fail if this point is the identity element
140
      void serialize_compressed_to(std::span<uint8_t> bytes) const;
141
142
      /// Return the fixed length encoding of SEC1 uncompressed encoding
143
      ///
144
      /// The output span must be exactly 1 + 2*field_element_bytes long
145
      ///
146
      /// This function will fail if this point is the identity element
147
      void serialize_uncompressed_to(std::span<uint8_t> bytes) const;
148
149
      /// Return the bytes of the affine x coordinate in a container
150
      ///
151
      /// This function will fail if this point is the identity element
152
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
153
173
      T x_bytes() const {
154
173
         T bytes(this->field_element_bytes());
155
173
         this->serialize_x_to(bytes);
156
173
         return bytes;
157
173
      }
158
159
      /// Return the bytes of the affine y coordinate in a container
160
      ///
161
      /// This function will fail if this point is the identity element
162
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
163
0
      T y_bytes() const {
164
0
         T bytes(this->field_element_bytes());
165
0
         this->serialize_y_to(bytes);
166
0
         return bytes;
167
0
      }
168
169
      /// Return the bytes of the affine x and y coordinates in a container
170
      ///
171
      /// This function will fail if this point is the identity element
172
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
173
0
      T xy_bytes() const {
174
0
         T bytes(2 * this->field_element_bytes());
175
0
         this->serialize_xy_to(bytes);
176
0
         return bytes;
177
0
      }
Unexecuted instantiation: _ZNK5Botan14EC_AffinePoint8xy_bytesITkNS_8concepts21resizable_byte_bufferENSt3__16vectorIhNS_16secure_allocatorIhEEEEEET_v
Unexecuted instantiation: _ZNK5Botan14EC_AffinePoint8xy_bytesITkNS_8concepts21resizable_byte_bufferENSt3__16vectorIhNS3_9allocatorIhEEEEEET_v
178
179
      /// Return the bytes of the affine x and y coordinates in a container
180
      ///
181
      /// This function will fail if this point is the identity element
182
      template <concepts::resizable_byte_buffer T = std::vector<uint8_t>>
183
0
      T serialize_uncompressed() const {
184
0
         T bytes(1 + 2 * this->field_element_bytes());
185
0
         this->serialize_uncompressed_to(bytes);
186
0
         return bytes;
187
0
      }
188
189
      /// Return the bytes of the affine x and y coordinates in a container
190
      ///
191
      /// This function will fail if this point is the identity element
192
      template <concepts::resizable_byte_buffer T = std::vector<uint8_t>>
193
      T serialize_compressed() const {
194
         T bytes(1 + this->field_element_bytes());
195
         this->serialize_compressed_to(bytes);
196
         return bytes;
197
      }
198
199
      EC_AffinePoint(const EC_AffinePoint& other);
200
      EC_AffinePoint(EC_AffinePoint&& other) noexcept;
201
202
      EC_AffinePoint& operator=(const EC_AffinePoint& other);
203
      EC_AffinePoint& operator=(EC_AffinePoint&& other) noexcept;
204
205
      /**
206
      * Deprecated conversion
207
      */
208
      EC_AffinePoint(const EC_Group& group, const EC_Point& pt);
209
210
      /**
211
      * Deprecated conversion
212
      */
213
      EC_Point to_legacy_point() const;
214
215
      ~EC_AffinePoint();
216
217
773
      const EC_AffinePoint_Data& _inner() const { return inner(); }
218
219
      static EC_AffinePoint _from_inner(std::unique_ptr<EC_AffinePoint_Data> inner);
220
221
      const std::shared_ptr<const EC_Group_Data>& _group() const;
222
223
   private:
224
      friend class EC_Mul2Table;
225
226
      EC_AffinePoint(std::unique_ptr<EC_AffinePoint_Data> point);
227
228
13.6k
      const EC_AffinePoint_Data& inner() const { return *m_point; }
229
230
      std::unique_ptr<EC_AffinePoint_Data> m_point;
231
};
232
233
}  // namespace Botan
234
235
#endif