Botan  2.11.0
Crypto and TLS for C++11
ed25519_fe.h
Go to the documentation of this file.
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  ~FE_25519() { secure_scrub_memory(m_fe, sizeof(m_fe)); }
26 
27  /**
28  * Zero element
29  */
30  FE_25519(int init = 0)
31  {
32  if(init != 0 && init != 1)
33  throw Invalid_Argument("Invalid FE_25519 initial value");
34  clear_mem(m_fe, 10);
35  m_fe[0] = init;
36  }
37 
38  FE_25519(std::initializer_list<int32_t> x)
39  {
40  if(x.size() != 10)
41  throw Invalid_Argument("Invalid FE_25519 initializer list");
42  copy_mem(m_fe, x.begin(), 10);
43  }
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  {
48  m_fe[0] = static_cast<int32_t>(h0);
49  m_fe[1] = static_cast<int32_t>(h1);
50  m_fe[2] = static_cast<int32_t>(h2);
51  m_fe[3] = static_cast<int32_t>(h3);
52  m_fe[4] = static_cast<int32_t>(h4);
53  m_fe[5] = static_cast<int32_t>(h5);
54  m_fe[6] = static_cast<int32_t>(h6);
55  m_fe[7] = static_cast<int32_t>(h7);
56  m_fe[8] = static_cast<int32_t>(h8);
57  m_fe[9] = static_cast<int32_t>(h9);
58  }
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  {
71  uint8_t s[32];
72  to_bytes(s);
73 
74  uint8_t sum = 0;
75  for(size_t i = 0; i != 32; ++i)
76  { sum |= s[i]; }
77 
78  // TODO avoid ternary here
79  return (sum == 0) ? 1 : 0;
80  }
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  {
88  // TODO could avoid most of the to_bytes computation here
89  uint8_t s[32];
90  to_bytes(s);
91  return s[0] & 1;
92  }
93 
94  static FE_25519 add(const FE_25519& a, const FE_25519& b)
95  {
96  FE_25519 z;
97  for(size_t i = 0; i != 10; ++i)
98  { z[i] = a[i] + b[i]; }
99  return z;
100  }
101 
102  static FE_25519 sub(const FE_25519& a, const FE_25519& b)
103  {
104  FE_25519 z;
105  for(size_t i = 0; i != 10; ++i)
106  { z[i] = a[i] - b[i]; }
107  return z;
108  }
109 
110  static FE_25519 negate(const FE_25519& a)
111  {
112  FE_25519 z;
113  for(size_t i = 0; i != 10; ++i)
114  { z[i] = -a[i]; }
115  return z;
116  }
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  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  int32_t operator[](size_t i) const { return m_fe[i]; }
127  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  {
146  x.from_bytes(b);
147  }
148 
149 inline void fe_tobytes(uint8_t* b, const fe& x)
150  {
151  x.to_bytes(b);
152  }
153 
154 inline void fe_copy(fe& a, const fe& b)
155  {
156  a = b;
157  }
158 
159 inline int fe_isnonzero(const fe& x)
160  {
161  return x.is_zero() ? 0 : 1;
162  }
163 
164 inline int fe_isnegative(const fe& x)
165  {
166  return x.is_negative();
167  }
168 
169 
170 inline void fe_0(fe& x)
171  {
172  x = FE_25519();
173  }
174 
175 inline void fe_1(fe& x)
176  {
177  x = FE_25519(1);
178  }
179 
180 inline void fe_add(fe& x, const fe& a, const fe& b)
181  {
182  x = FE_25519::add(a, b);
183  }
184 
185 inline void fe_sub(fe& x, const fe& a, const fe& b)
186  {
187  x = FE_25519::sub(a, b);
188  }
189 
190 inline void fe_neg(fe& x, const fe& z)
191  {
192  x = FE_25519::negate(z);
193  }
194 
195 inline void fe_mul(fe& x, const fe& a, const fe& b)
196  {
197  x = FE_25519::mul(a, b);
198  }
199 
200 inline void fe_sq(fe& x, const fe& z)
201  {
202  x = FE_25519::sqr(z);
203  }
204 
205 inline void fe_sq_iter(fe& x, const fe& z, size_t iter)
206  {
207  x = FE_25519::sqr_iter(z, iter);
208  }
209 
210 inline void fe_sq2(fe& x, const fe& z)
211  {
212  x = FE_25519::sqr2(z);
213  }
214 
215 inline void fe_invert(fe& x, const fe& z)
216  {
217  x = FE_25519::invert(z);
218  }
219 
220 inline void fe_pow22523(fe& x, const fe& y)
221  {
223  }
224 
225 }
226 
227 #endif
FE_25519(int64_t h0, int64_t h1, int64_t h2, int64_t h3, int64_t h4, int64_t h5, int64_t h6, int64_t h7, int64_t h8, int64_t h9)
Definition: ed25519_fe.h:45
BigInt const BigInt & x
Definition: numthry.h:139
static FE_25519 pow_22523(const FE_25519 &a)
Definition: ed25519_fe.cpp:50
static FE_25519 invert(const FE_25519 &a)
Definition: ed25519_fe.cpp:17
static FE_25519 negate(const FE_25519 &a)
Definition: ed25519_fe.h:110
void fe_neg(fe &x, const fe &z)
Definition: ed25519_fe.h:190
void fe_add(fe &x, const fe &a, const fe &b)
Definition: ed25519_fe.h:180
void from_bytes(const uint8_t b[32])
Definition: ed25519_fe.cpp:605
bool const OID & b
Definition: asn1_oid.h:109
int32_t & operator[](size_t i)
Definition: ed25519_fe.h:127
void fe_0(fe &x)
Definition: ed25519_fe.h:170
void fe_sq(fe &x, const fe &z)
Definition: ed25519_fe.h:200
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:111
void to_bytes(uint8_t b[32]) const
Definition: ed25519_fe.cpp:667
void fe_invert(fe &x, const fe &z)
Definition: ed25519_fe.h:215
FE_25519 & operator=(const FE_25519 &other)=default
void fe_1(fe &x)
Definition: ed25519_fe.h:175
int fe_isnegative(const fe &x)
Definition: ed25519_fe.h:164
void fe_sub(fe &x, const fe &a, const fe &b)
Definition: ed25519_fe.h:185
void fe_sq2(fe &x, const fe &z)
Definition: ed25519_fe.h:210
void fe_copy(fe &a, const fe &b)
Definition: ed25519_fe.h:154
size_t const BigInt & a
Definition: numthry.h:111
static FE_25519 sqr_iter(const FE_25519 &a, size_t iter)
Definition: ed25519_fe.cpp:337
static FE_25519 sqr2(const FE_25519 &a)
Definition: ed25519_fe.cpp:479
void fe_tobytes(uint8_t *b, const fe &x)
Definition: ed25519_fe.h:149
void fe_sq_iter(fe &x, const fe &z, size_t iter)
Definition: ed25519_fe.h:205
static FE_25519 mul(const FE_25519 &a, const FE_25519 &b)
Definition: ed25519_fe.cpp:115
void copy_mem(T *out, const T *in, size_t n)
Definition: mem_ops.h:122
Definition: alg_id.cpp:13
int fe_isnonzero(const fe &x)
Definition: ed25519_fe.h:159
FE_25519(std::initializer_list< int32_t > x)
Definition: ed25519_fe.h:38
FE_25519(int init=0)
Definition: ed25519_fe.h:30
int32_t operator[](size_t i) const
Definition: ed25519_fe.h:126
void secure_scrub_memory(void *ptr, size_t n)
Definition: os_utils.cpp:61
int(* init)(CTX *)
FE_25519 fe
Definition: ed25519_fe.h:134
static FE_25519 add(const FE_25519 &a, const FE_25519 &b)
Definition: ed25519_fe.h:94
static FE_25519 sqr(const FE_25519 &a)
Definition: ed25519_fe.h:120
const OctetString & y
Definition: symkey.h:126
static FE_25519 sub(const FE_25519 &a, const FE_25519 &b)
Definition: ed25519_fe.h:102
void fe_frombytes(fe &x, const uint8_t *b)
Definition: ed25519_fe.h:144
void fe_pow22523(fe &x, const fe &y)
Definition: ed25519_fe.h:220
bool is_zero() const
Definition: ed25519_fe.h:69
bool is_negative() const
Definition: ed25519_fe.h:86
void fe_mul(fe &x, const fe &a, const fe &b)
Definition: ed25519_fe.h:195