Coverage Report

Created: 2019-09-11 14:12

/src/botan/build/include/botan/internal/ed25519_fe.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Ed25519 field element
3
* (C) 2017 Ribose Inc
4
*
5
* Based on the public domain code from SUPERCOP ref10 by
6
* Peter Schwabe, Daniel J. Bernstein, Niels Duif, Tanja Lange, Bo-Yin Yang
7
*
8
* Botan is released under the Simplified BSD License (see license.txt)
9
*/
10
11
#ifndef BOTAN_ED25519_FE_H_
12
#define BOTAN_ED25519_FE_H_
13
14
#include <botan/mem_ops.h>
15
#include <botan/exceptn.h>
16
17
namespace Botan {
18
19
/**
20
* An element of the field \\Z/(2^255-19)
21
*/
22
class FE_25519
23
   {
24
   public:
25
328k
      ~FE_25519() { secure_scrub_memory(m_fe, sizeof(m_fe)); }
26
27
      /**
28
      * Zero element
29
      */
30
      FE_25519(int init = 0)
31
157k
         {
32
157k
         if(init != 0 && init != 1)
33
0
            throw Invalid_Argument("Invalid FE_25519 initial value");
34
157k
         clear_mem(m_fe, 10);
35
157k
         m_fe[0] = init;
36
157k
         }
37
38
      FE_25519(std::initializer_list<int32_t> x)
39
9.24k
         {
40
9.24k
         if(x.size() != 10)
41
0
            throw Invalid_Argument("Invalid FE_25519 initializer list");
42
9.24k
         copy_mem(m_fe, x.begin(), 10);
43
9.24k
         }
44
45
      FE_25519(int64_t h0, int64_t h1, int64_t h2, int64_t h3, int64_t h4,
46
               int64_t h5, int64_t h6, int64_t h7, int64_t h8, int64_t h9)
47
170k
         {
48
170k
         m_fe[0] = static_cast<int32_t>(h0);
49
170k
         m_fe[1] = static_cast<int32_t>(h1);
50
170k
         m_fe[2] = static_cast<int32_t>(h2);
51
170k
         m_fe[3] = static_cast<int32_t>(h3);
52
170k
         m_fe[4] = static_cast<int32_t>(h4);
53
170k
         m_fe[5] = static_cast<int32_t>(h5);
54
170k
         m_fe[6] = static_cast<int32_t>(h6);
55
170k
         m_fe[7] = static_cast<int32_t>(h7);
56
170k
         m_fe[8] = static_cast<int32_t>(h8);
57
170k
         m_fe[9] = static_cast<int32_t>(h9);
58
170k
         }
59
60
      FE_25519(const FE_25519& other) = default;
61
      FE_25519& operator=(const FE_25519& other) = default;
62
63
      FE_25519(FE_25519&& other) = default;
64
      FE_25519& operator=(FE_25519&& other) = default;
65
66
      void from_bytes(const uint8_t b[32]);
67
      void to_bytes(uint8_t b[32]) const;
68
69
      bool is_zero() const
70
99
         {
71
99
         uint8_t s[32];
72
99
         to_bytes(s);
73
99
74
99
         uint8_t sum = 0;
75
3.26k
         for(size_t i = 0; i != 32; ++i)
76
3.16k
            { sum |= s[i]; }
77
99
78
99
         // TODO avoid ternary here
79
99
         return (sum == 0) ? 1 : 0;
80
99
         }
81
82
      /*
83
      return 1 if f is in {1,3,5,...,q-2}
84
      return 0 if f is in {0,2,4,...,q-1}
85
      */
86
      bool is_negative() const
87
145
         {
88
145
         // TODO could avoid most of the to_bytes computation here
89
145
         uint8_t s[32];
90
145
         to_bytes(s);
91
145
         return s[0] & 1;
92
145
         }
93
94
      static FE_25519 add(const FE_25519& a, const FE_25519& b)
95
57.8k
         {
96
57.8k
         FE_25519 z;
97
636k
         for(size_t i = 0; i != 10; ++i)
98
578k
            { z[i] = a[i] + b[i]; }
99
57.8k
         return z;
100
57.8k
         }
101
102
      static FE_25519 sub(const FE_25519& a, const FE_25519& b)
103
70.3k
         {
104
70.3k
         FE_25519 z;
105
774k
         for(size_t i = 0; i != 10; ++i)
106
703k
            { z[i] = a[i] - b[i]; }
107
70.3k
         return z;
108
70.3k
         }
109
110
      static FE_25519 negate(const FE_25519& a)
111
239
         {
112
239
         FE_25519 z;
113
2.62k
         for(size_t i = 0; i != 10; ++i)
114
2.39k
            { z[i] = -a[i]; }
115
239
         return z;
116
239
         }
117
118
      static FE_25519 mul(const FE_25519& a, const FE_25519& b);
119
      static FE_25519 sqr_iter(const FE_25519& a, size_t iter);
120
54.1k
      static FE_25519 sqr(const FE_25519& a) { return sqr_iter(a, 1); }
121
      static FE_25519 sqr2(const FE_25519& a);
122
      static FE_25519 pow_22523(const FE_25519& a);
123
      static FE_25519 invert(const FE_25519& a);
124
125
      // TODO remove
126
5.30M
      int32_t operator[](size_t i) const { return m_fe[i]; }
127
1.36M
      int32_t& operator[](size_t i) { return m_fe[i]; }
128
129
   private:
130
131
      int32_t m_fe[10];
132
   };
133
134
typedef FE_25519 fe;
135
136
/*
137
fe means field element.
138
Here the field is
139
An element t, entries t[0]...t[9], represents the integer
140
t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
141
Bounds on each t[i] vary depending on context.
142
*/
143
144
inline void fe_frombytes(fe& x, const uint8_t* b)
145
72
   {
146
72
   x.from_bytes(b);
147
72
   }
148
149
inline void fe_tobytes(uint8_t* b, const fe& x)
150
74
   {
151
74
   x.to_bytes(b);
152
74
   }
153
154
inline void fe_copy(fe& a, const fe& b)
155
568
   {
156
568
   a = b;
157
568
   }
158
159
inline int fe_isnonzero(const fe& x)
160
99
   {
161
99
   return x.is_zero() ? 0 : 1;
162
99
   }
163
164
inline int fe_isnegative(const fe& x)
165
145
   {
166
145
   return x.is_negative();
167
145
   }
168
169
170
inline void fe_0(fe& x)
171
269
   {
172
269
   x = FE_25519();
173
269
   }
174
175
inline void fe_1(fe& x)
176
604
   {
177
604
   x = FE_25519(1);
178
604
   }
179
180
inline void fe_add(fe& x, const fe& a, const fe& b)
181
57.8k
   {
182
57.8k
   x = FE_25519::add(a, b);
183
57.8k
   }
184
185
inline void fe_sub(fe& x, const fe& a, const fe& b)
186
70.3k
   {
187
70.3k
   x = FE_25519::sub(a, b);
188
70.3k
   }
189
190
inline void fe_neg(fe& x, const fe& z)
191
239
   {
192
239
   x = FE_25519::negate(z);
193
239
   }
194
195
inline void fe_mul(fe& x, const fe& a, const fe& b)
196
97.6k
   {
197
97.6k
   x = FE_25519::mul(a, b);
198
97.6k
   }
199
200
inline void fe_sq(fe& x, const fe& z)
201
54.1k
   {
202
54.1k
   x = FE_25519::sqr(z);
203
54.1k
   }
204
205
inline void fe_sq_iter(fe& x, const fe& z, size_t iter)
206
1.31k
   {
207
1.31k
   x = FE_25519::sqr_iter(z, iter);
208
1.31k
   }
209
210
inline void fe_sq2(fe& x, const fe& z)
211
17.8k
   {
212
17.8k
   x = FE_25519::sqr2(z);
213
17.8k
   }
214
215
inline void fe_invert(fe& x, const fe& z)
216
74
   {
217
74
   x = FE_25519::invert(z);
218
74
   }
219
220
inline void fe_pow22523(fe& x, const fe& y)
221
72
   {
222
72
   x = FE_25519::pow_22523(y);
223
72
   }
224
225
}
226
227
#endif