Coverage Report

Created: 2024-11-21 06:51

/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
class BOTAN_UNSTABLE_API EC_AffinePoint final {
30
   public:
31
      /// Point deserialization. Throws if wrong length or not a valid point
32
      ///
33
      /// This accepts SEC1 compressed or uncompressed formats
34
      EC_AffinePoint(const EC_Group& group, std::span<const uint8_t> bytes);
35
36
      /// Point deserialization. Returns nullopt if wrong length or not a valid point
37
      ///
38
      /// This accepts SEC1 compressed or uncompressed formats
39
      static std::optional<EC_AffinePoint> deserialize(const EC_Group& group, std::span<const uint8_t> bytes);
40
41
      /// Create a point from a pair (x,y) of integers
42
      ///
43
      /// The integers must be within the field - in the range [0,p) and must
44
      /// satisfy the curve equation
45
      static std::optional<EC_AffinePoint> from_bigint_xy(const EC_Group& group, const BigInt& x, const BigInt& y);
46
47
      /// Multiply by the group generator returning a complete point
48
      ///
49
      /// Workspace argument is transitional
50
      static EC_AffinePoint g_mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws);
51
52
      /// Return the identity element
53
      static EC_AffinePoint identity(const EC_Group& group);
54
55
      /// Return the standard group generator
56
      static EC_AffinePoint generator(const EC_Group& group);
57
58
      /// Hash to curve (RFC 9380), random oracle variant
59
      ///
60
      /// Only supported for specific groups
61
      static EC_AffinePoint hash_to_curve_ro(const EC_Group& group,
62
                                             std::string_view hash_fn,
63
                                             std::span<const uint8_t> input,
64
                                             std::span<const uint8_t> domain_sep);
65
66
      /// Hash to curve (RFC 9380), non uniform variant
67
      ///
68
      /// Only supported for specific groups
69
      static EC_AffinePoint hash_to_curve_nu(const EC_Group& group,
70
                                             std::string_view hash_fn,
71
                                             std::span<const uint8_t> input,
72
                                             std::span<const uint8_t> domain_sep);
73
74
      /// Multiply a point by a scalar returning a complete point
75
      ///
76
      /// Workspace argument is transitional
77
      EC_AffinePoint mul(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws) const;
78
79
      /// Compute 2-ary multiscalar multiplication - p*x + q*y
80
      ///
81
      /// This operation runs in constant time with respect to p, x, q, and y
82
      static EC_AffinePoint mul_px_qy(const EC_AffinePoint& p,
83
                                      const EC_Scalar& x,
84
                                      const EC_AffinePoint& q,
85
                                      const EC_Scalar& y,
86
                                      RandomNumberGenerator& rng);
87
88
      /// Return the number of bytes of a field element
89
      ///
90
      /// A point consists of two field elements, plus possibly a header
91
      size_t field_element_bytes() const;
92
93
      /// Return true if this point is the identity element
94
      bool is_identity() const;
95
96
      /// Write the fixed length encoding of affine x coordinate
97
      ///
98
      /// The output span must be exactly field_element_bytes long
99
      ///
100
      /// This function will fail if this point is the identity element
101
      void serialize_x_to(std::span<uint8_t> bytes) const;
102
103
      /// Write the fixed length encoding of affine y coordinate
104
      ///
105
      /// The output span must be exactly field_element_bytes long
106
      ///
107
      /// This function will fail if this point is the identity element
108
      void serialize_y_to(std::span<uint8_t> bytes) const;
109
110
      /// Write the fixed length encoding of affine x and y coordinates
111
      ///
112
      /// The output span must be exactly 2*field_element_bytes long
113
      ///
114
      /// This function will fail if this point is the identity element
115
      void serialize_xy_to(std::span<uint8_t> bytes) const;
116
117
      /// Write the fixed length SEC1 compressed encoding
118
      ///
119
      /// The output span must be exactly 1 + field_element_bytes long
120
      ///
121
      /// This function will fail if this point is the identity element
122
      void serialize_compressed_to(std::span<uint8_t> bytes) const;
123
124
      /// Return the fixed length encoding of SEC1 uncompressed encoding
125
      ///
126
      /// The output span must be exactly 1 + 2*field_element_bytes long
127
      ///
128
      /// This function will fail if this point is the identity element
129
      void serialize_uncompressed_to(std::span<uint8_t> bytes) const;
130
131
      /// Return the bytes of the affine x coordinate in a container
132
      ///
133
      /// This function will fail if this point is the identity element
134
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
135
0
      T x_bytes() const {
136
0
         T bytes(this->field_element_bytes());
137
0
         this->serialize_x_to(bytes);
138
0
         return bytes;
139
0
      }
140
141
      /// Return the bytes of the affine y coordinate in a container
142
      ///
143
      /// This function will fail if this point is the identity element
144
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
145
      T y_bytes() const {
146
         T bytes(this->field_element_bytes());
147
         this->serialize_y_to(bytes);
148
         return bytes;
149
      }
150
151
      /// Return the bytes of the affine x and y coordinates in a container
152
      ///
153
      /// This function will fail if this point is the identity element
154
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
155
      T xy_bytes() const {
156
         T bytes(2 * this->field_element_bytes());
157
         this->serialize_xy_to(bytes);
158
         return bytes;
159
      }
160
161
      /// Return the bytes of the affine x and y coordinates in a container
162
      ///
163
      /// This function will fail if this point is the identity element
164
      template <concepts::resizable_byte_buffer T = std::vector<uint8_t>>
165
0
      T serialize_uncompressed() const {
166
0
         T bytes(1 + 2 * this->field_element_bytes());
167
0
         this->serialize_uncompressed_to(bytes);
168
0
         return bytes;
169
0
      }
170
171
      /// Return the bytes of the affine x and y coordinates in a container
172
      ///
173
      /// This function will fail if this point is the identity element
174
      template <concepts::resizable_byte_buffer T = std::vector<uint8_t>>
175
      T serialize_compressed() const {
176
         T bytes(1 + this->field_element_bytes());
177
         this->serialize_compressed_to(bytes);
178
         return bytes;
179
      }
180
181
      EC_AffinePoint(const EC_AffinePoint& other);
182
      EC_AffinePoint(EC_AffinePoint&& other) noexcept;
183
184
      EC_AffinePoint& operator=(const EC_AffinePoint& other);
185
      EC_AffinePoint& operator=(EC_AffinePoint&& other) noexcept;
186
187
      /**
188
      * Deprecated conversion
189
      */
190
      EC_AffinePoint(const EC_Group& group, const EC_Point& pt);
191
192
      /**
193
      * Deprecated conversion
194
      */
195
      EC_Point to_legacy_point() const;
196
197
      ~EC_AffinePoint();
198
199
0
      const EC_AffinePoint_Data& _inner() const { return inner(); }
200
201
      static EC_AffinePoint _from_inner(std::unique_ptr<EC_AffinePoint_Data> inner);
202
203
      const std::shared_ptr<const EC_Group_Data>& _group() const;
204
205
   private:
206
      friend class EC_Mul2Table;
207
208
      EC_AffinePoint(std::unique_ptr<EC_AffinePoint_Data> point);
209
210
0
      const EC_AffinePoint_Data& inner() const { return *m_point; }
211
212
      std::unique_ptr<EC_AffinePoint_Data> m_point;
213
};
214
215
}  // namespace Botan
216
217
#endif