Coverage Report

Created: 2024-06-28 06:19

/src/botan/build/include/public/botan/curve_gfp.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Elliptic curves over GF(p)
3
*
4
* (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke
5
*     2010-2011,2012,2014 Jack Lloyd
6
*
7
* Botan is released under the Simplified BSD License (see license.txt)
8
*/
9
10
#ifndef BOTAN_GFP_CURVE_H_
11
#define BOTAN_GFP_CURVE_H_
12
13
#include <botan/bigint.h>
14
#include <memory>
15
16
// Currently exposed in EC_Point
17
//BOTAN_FUTURE_INTERNAL_HEADER(curve_gfp.h)
18
19
namespace Botan {
20
21
class BOTAN_UNSTABLE_API CurveGFp_Repr {
22
   public:
23
26
      virtual ~CurveGFp_Repr() = default;
24
25
      friend class CurveGFp;
26
27
   protected:
28
      virtual const BigInt& get_p() const = 0;
29
      virtual const BigInt& get_a() const = 0;
30
      virtual const BigInt& get_b() const = 0;
31
32
134k
      size_t get_p_words() const {
33
134k
         const size_t W_bits = sizeof(word) * 8;
34
134k
         return (get_p_bits() + W_bits - 1) / W_bits;
35
134k
      }
36
37
      virtual size_t get_p_bits() const = 0;
38
39
      virtual size_t get_ws_size() const = 0;
40
41
      virtual bool is_one(const BigInt& x) const = 0;
42
43
      virtual bool a_is_zero() const = 0;
44
45
      virtual bool a_is_minus_3() const = 0;
46
47
      /*
48
      * Returns to_curve_rep(get_a())
49
      */
50
      virtual const BigInt& get_a_rep() const = 0;
51
52
      /*
53
      * Returns to_curve_rep(get_b())
54
      */
55
      virtual const BigInt& get_b_rep() const = 0;
56
57
      /*
58
      * Returns to_curve_rep(1)
59
      */
60
      virtual const BigInt& get_1_rep() const = 0;
61
62
      virtual BigInt invert_element(const BigInt& x, secure_vector<word>& ws) const = 0;
63
64
      virtual void to_curve_rep(BigInt& x, secure_vector<word>& ws) const = 0;
65
66
      virtual void from_curve_rep(BigInt& x, secure_vector<word>& ws) const = 0;
67
68
2.75M
      void curve_mul(BigInt& z, const BigInt& x, const BigInt& y, secure_vector<word>& ws) const {
69
2.75M
         BOTAN_DEBUG_ASSERT(x.sig_words() <= get_p_words());
70
2.75M
         curve_mul_words(z, x._data(), x.size(), y, ws);
71
2.75M
      }
72
73
      virtual void curve_mul_words(
74
         BigInt& z, const word x_words[], size_t x_size, const BigInt& y, secure_vector<word>& ws) const = 0;
75
76
2.06M
      void curve_sqr(BigInt& z, const BigInt& x, secure_vector<word>& ws) const {
77
2.06M
         BOTAN_DEBUG_ASSERT(x.sig_words() <= get_p_words());
78
2.06M
         curve_sqr_words(z, x._data(), x.size(), ws);
79
2.06M
      }
80
81
      virtual void curve_sqr_words(BigInt& z, const word x_words[], size_t x_size, secure_vector<word>& ws) const = 0;
82
};
83
84
/**
85
* This class represents an elliptic curve over GF(p)
86
*
87
* There should not be any reason for applications to use this type.
88
* If you need EC primitives use the interfaces EC_Group and EC_Point
89
*
90
* It is likely this class will be removed entirely in a future major
91
* release.
92
*/
93
class BOTAN_UNSTABLE_API CurveGFp final {
94
   public:
95
      /**
96
      * @return curve coefficient a
97
      */
98
11
      const BigInt& get_a() const { return m_repr->get_a(); }
99
100
      /**
101
      * @return curve coefficient b
102
      */
103
11
      const BigInt& get_b() const { return m_repr->get_b(); }
104
105
      /**
106
      * Get prime modulus of the field of the curve
107
      * @return prime modulus of the field of the curve
108
      */
109
478k
      const BigInt& get_p() const { return m_repr->get_p(); }
110
111
   private:
112
      friend class EC_Point;
113
      friend class EC_Group;
114
      friend class EC_Group_Data;
115
      friend class EC_Point_Base_Point_Precompute;
116
      friend class EC_Point_Var_Point_Precompute;
117
118
      /**
119
      * Create an uninitialized CurveGFp
120
      */
121
27.3k
      CurveGFp() = default;
122
123
      /**
124
      * Construct the elliptic curve E: y^2 = x^3 + ax + b over GF(p)
125
      * @param p prime number of the field
126
      * @param a first coefficient
127
      * @param b second coefficient
128
      */
129
26
      CurveGFp(const BigInt& p, const BigInt& a, const BigInt& b) : m_repr(choose_repr(p, a, b)) {}
130
131
29.0k
      CurveGFp(const CurveGFp&) = default;
132
133
12.8k
      CurveGFp& operator=(const CurveGFp&) = default;
134
135
134k
      size_t get_p_words() const { return m_repr->get_p_words(); }
136
137
0
      size_t get_p_bits() const { return m_repr->get_p_bits(); }
138
139
0
      size_t get_p_bytes() const { return (get_p_bits() + 7) / 8; }
140
141
476k
      size_t get_ws_size() const { return m_repr->get_ws_size(); }
142
143
100k
      const BigInt& get_a_rep() const { return m_repr->get_a_rep(); }
144
145
3.29k
      const BigInt& get_b_rep() const { return m_repr->get_b_rep(); }
146
147
8.80k
      const BigInt& get_1_rep() const { return m_repr->get_1_rep(); }
148
149
219k
      bool a_is_minus_3() const { return m_repr->a_is_minus_3(); }
150
151
241k
      bool a_is_zero() const { return m_repr->a_is_zero(); }
152
153
1.94k
      bool is_one(const BigInt& x) const { return m_repr->is_one(x); }
154
155
1.92k
      BigInt invert_element(const BigInt& x, secure_vector<word>& ws) const { return m_repr->invert_element(x, ws); }
156
157
3.02k
      void to_rep(BigInt& x, secure_vector<word>& ws) const { m_repr->to_curve_rep(x, ws); }
158
159
1.75k
      void from_rep(BigInt& x, secure_vector<word>& ws) const { m_repr->from_curve_rep(x, ws); }
160
161
5.78k
      BigInt from_rep_to_tmp(const BigInt& x, secure_vector<word>& ws) const {
162
5.78k
         BigInt xt(x);
163
5.78k
         m_repr->from_curve_rep(xt, ws);
164
5.78k
         return xt;
165
5.78k
      }
166
167
      // TODO: from_rep taking && ref
168
169
2.65M
      void mul(BigInt& z, const BigInt& x, const BigInt& y, secure_vector<word>& ws) const {
170
2.65M
         m_repr->curve_mul(z, x, y, ws);
171
2.65M
      }
172
173
711k
      void mul(BigInt& z, const word x_w[], size_t x_size, const BigInt& y, secure_vector<word>& ws) const {
174
711k
         m_repr->curve_mul_words(z, x_w, x_size, y, ws);
175
711k
      }
176
177
1.88M
      void sqr(BigInt& z, const BigInt& x, secure_vector<word>& ws) const { m_repr->curve_sqr(z, x, ws); }
178
179
123k
      void sqr(BigInt& z, const word x_w[], size_t x_size, secure_vector<word>& ws) const {
180
123k
         m_repr->curve_sqr_words(z, x_w, x_size, ws);
181
123k
      }
182
183
0
      BigInt mul(const BigInt& x, const BigInt& y, secure_vector<word>& ws) const { return mul_to_tmp(x, y, ws); }
184
185
0
      BigInt sqr(const BigInt& x, secure_vector<word>& ws) const { return sqr_to_tmp(x, ws); }
186
187
89.7k
      BigInt mul_to_tmp(const BigInt& x, const BigInt& y, secure_vector<word>& ws) const {
188
89.7k
         BigInt z;
189
89.7k
         m_repr->curve_mul(z, x, y, ws);
190
89.7k
         return z;
191
89.7k
      }
192
193
13.4k
      BigInt sqr_to_tmp(const BigInt& x, secure_vector<word>& ws) const {
194
13.4k
         BigInt z;
195
13.4k
         m_repr->curve_sqr(z, x, ws);
196
13.4k
         return z;
197
13.4k
      }
198
199
28.5k
      void swap(CurveGFp& other) { std::swap(m_repr, other.m_repr); }
200
201
0
      friend void swap(CurveGFp& x, CurveGFp& y) { x.swap(y); }
202
203
      /**
204
      * Equality operator
205
      * @param other a curve
206
      * @return true iff *this is the same as other
207
      */
208
133k
      inline bool operator==(const CurveGFp& other) const {
209
133k
         if(m_repr.get() == other.m_repr.get()) {
210
133k
            return true;
211
133k
         }
212
213
0
         return (get_p() == other.get_p()) && (get_a() == other.get_a()) && (get_b() == other.get_b());
214
133k
      }
215
216
27
      inline bool operator!=(const CurveGFp& other) const = default;
217
218
   private:
219
      static std::shared_ptr<CurveGFp_Repr> choose_repr(const BigInt& p, const BigInt& a, const BigInt& b);
220
221
      std::shared_ptr<CurveGFp_Repr> m_repr;
222
};
223
224
}  // namespace Botan
225
226
#endif