Botan 3.8.1
Crypto and TLS for C&
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/exceptn.h>
15#include <botan/mem_ops.h>
16
17namespace Botan {
18
19/**
20* An element of the field \\Z/(2^255-19)
21*/
22class FE_25519 {
23 public:
24 ~FE_25519() { secure_scrub_memory(m_fe, sizeof(m_fe)); }
25
26 /**
27 * Zero element
28 */
29 FE_25519(int init = 0) {
30 if(init != 0 && init != 1) {
31 throw Invalid_Argument("Invalid FE_25519 initial value");
32 }
33 clear_mem(m_fe, 10);
34 m_fe[0] = init;
35 }
36
37 FE_25519(std::initializer_list<int32_t> x) {
38 if(x.size() != 10) {
39 throw Invalid_Argument("Invalid FE_25519 initializer list");
40 }
41 copy_mem(m_fe, x.begin(), 10);
42 }
43
44 FE_25519(int64_t h0,
45 int64_t h1,
46 int64_t h2,
47 int64_t h3,
48 int64_t h4,
49 int64_t h5,
50 int64_t h6,
51 int64_t h7,
52 int64_t h8,
53 int64_t h9) {
54 m_fe[0] = static_cast<int32_t>(h0);
55 m_fe[1] = static_cast<int32_t>(h1);
56 m_fe[2] = static_cast<int32_t>(h2);
57 m_fe[3] = static_cast<int32_t>(h3);
58 m_fe[4] = static_cast<int32_t>(h4);
59 m_fe[5] = static_cast<int32_t>(h5);
60 m_fe[6] = static_cast<int32_t>(h6);
61 m_fe[7] = static_cast<int32_t>(h7);
62 m_fe[8] = static_cast<int32_t>(h8);
63 m_fe[9] = static_cast<int32_t>(h9);
64 }
65
66 FE_25519(const FE_25519& other) = default;
67 FE_25519& operator=(const FE_25519& other) = default;
68
69 FE_25519(FE_25519&& other) = default;
70 FE_25519& operator=(FE_25519&& other) = default;
71
72 void from_bytes(const uint8_t b[32]);
73 void to_bytes(uint8_t b[32]) const;
74
75 bool is_zero() const {
76 uint8_t s[32];
77 to_bytes(s);
78
79 uint8_t sum = 0;
80 for(size_t i = 0; i != 32; ++i) {
81 sum |= s[i];
82 }
83
84 return (sum == 0);
85 }
86
87 /*
88 return 1 if f is in {1,3,5,...,q-2}
89 return 0 if f is in {0,2,4,...,q-1}
90 */
91 bool is_negative() const {
92 // TODO could avoid most of the to_bytes computation here
93 uint8_t s[32];
94 to_bytes(s);
95 return s[0] & 1;
96 }
97
98 static FE_25519 add(const FE_25519& a, const FE_25519& b) {
99 FE_25519 z;
100 for(size_t i = 0; i != 10; ++i) {
101 z[i] = a[i] + b[i];
102 }
103 return z;
104 }
105
106 static FE_25519 sub(const FE_25519& a, const FE_25519& b) {
107 FE_25519 z;
108 for(size_t i = 0; i != 10; ++i) {
109 z[i] = a[i] - b[i];
110 }
111 return z;
112 }
113
114 static FE_25519 negate(const FE_25519& a) {
115 FE_25519 z;
116 for(size_t i = 0; i != 10; ++i) {
117 z[i] = -a[i];
118 }
119 return z;
120 }
121
122 static FE_25519 mul(const FE_25519& a, const FE_25519& b);
123 static FE_25519 sqr_iter(const FE_25519& a, size_t iter);
124
125 static FE_25519 sqr(const FE_25519& a) { return sqr_iter(a, 1); }
126
127 static FE_25519 sqr2(const FE_25519& a);
128 static FE_25519 pow_22523(const FE_25519& a);
129 static FE_25519 invert(const FE_25519& a);
130
131 // TODO remove
132 int32_t operator[](size_t i) const { return m_fe[i]; }
133
134 int32_t& operator[](size_t i) { return m_fe[i]; }
135
136 private:
137 int32_t m_fe[10];
138};
139
140/*
141fe means field element.
142Here the field is
143An element t, entries t[0]...t[9], represents the integer
144t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
145Bounds on each t[i] vary depending on context.
146*/
147
148inline void fe_frombytes(FE_25519& x, const uint8_t* b) {
149 x.from_bytes(b);
150}
151
152inline void fe_tobytes(uint8_t* b, const FE_25519& x) {
153 x.to_bytes(b);
154}
155
156inline void fe_copy(FE_25519& a, const FE_25519& b) {
157 a = b;
158}
159
160inline int fe_isnonzero(const FE_25519& x) {
161 return x.is_zero() ? 0 : 1;
162}
163
164inline int fe_isnegative(const FE_25519& x) {
165 return x.is_negative();
166}
167
168inline void fe_0(FE_25519& x) {
169 x = FE_25519();
170}
171
172inline void fe_1(FE_25519& x) {
173 x = FE_25519(1);
174}
175
176inline void fe_add(FE_25519& x, const FE_25519& a, const FE_25519& b) {
177 x = FE_25519::add(a, b);
178}
179
180inline void fe_sub(FE_25519& x, const FE_25519& a, const FE_25519& b) {
181 x = FE_25519::sub(a, b);
182}
183
184inline void fe_neg(FE_25519& x, const FE_25519& z) {
185 x = FE_25519::negate(z);
186}
187
188inline void fe_mul(FE_25519& x, const FE_25519& a, const FE_25519& b) {
189 x = FE_25519::mul(a, b);
190}
191
192inline void fe_sq(FE_25519& x, const FE_25519& z) {
193 x = FE_25519::sqr(z);
194}
195
196inline void fe_sq_iter(FE_25519& x, const FE_25519& z, size_t iter) {
197 x = FE_25519::sqr_iter(z, iter);
198}
199
200inline void fe_sq2(FE_25519& x, const FE_25519& z) {
201 x = FE_25519::sqr2(z);
202}
203
204inline void fe_invert(FE_25519& x, const FE_25519& z) {
205 x = FE_25519::invert(z);
206}
207
208inline void fe_pow22523(FE_25519& x, const FE_25519& y) {
209 x = FE_25519::pow_22523(y);
210}
211
212} // namespace Botan
213
214#endif
static FE_25519 add(const FE_25519 &a, const FE_25519 &b)
Definition ed25519_fe.h:98
FE_25519 & operator=(FE_25519 &&other)=default
static FE_25519 sub(const FE_25519 &a, const FE_25519 &b)
Definition ed25519_fe.h:106
FE_25519(const FE_25519 &other)=default
bool is_negative() const
Definition ed25519_fe.h:91
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:44
void to_bytes(uint8_t b[32]) const
void from_bytes(const uint8_t b[32])
static FE_25519 invert(const FE_25519 &a)
static FE_25519 sqr(const FE_25519 &a)
Definition ed25519_fe.h:125
FE_25519(std::initializer_list< int32_t > x)
Definition ed25519_fe.h:37
FE_25519 & operator=(const FE_25519 &other)=default
static FE_25519 mul(const FE_25519 &a, const FE_25519 &b)
FE_25519(FE_25519 &&other)=default
int32_t & operator[](size_t i)
Definition ed25519_fe.h:134
static FE_25519 negate(const FE_25519 &a)
Definition ed25519_fe.h:114
int32_t operator[](size_t i) const
Definition ed25519_fe.h:132
static FE_25519 pow_22523(const FE_25519 &a)
FE_25519(int init=0)
Definition ed25519_fe.h:29
static FE_25519 sqr_iter(const FE_25519 &a, size_t iter)
bool is_zero() const
Definition ed25519_fe.h:75
static FE_25519 sqr2(const FE_25519 &a)
void fe_sq_iter(FE_25519 &x, const FE_25519 &z, size_t iter)
Definition ed25519_fe.h:196
void fe_0(FE_25519 &x)
Definition ed25519_fe.h:168
void fe_copy(FE_25519 &a, const FE_25519 &b)
Definition ed25519_fe.h:156
void fe_1(FE_25519 &x)
Definition ed25519_fe.h:172
void fe_pow22523(FE_25519 &x, const FE_25519 &y)
Definition ed25519_fe.h:208
void fe_tobytes(uint8_t *b, const FE_25519 &x)
Definition ed25519_fe.h:152
void fe_invert(FE_25519 &x, const FE_25519 &z)
Definition ed25519_fe.h:204
void fe_sq(FE_25519 &x, const FE_25519 &z)
Definition ed25519_fe.h:192
int fe_isnonzero(const FE_25519 &x)
Definition ed25519_fe.h:160
void secure_scrub_memory(void *ptr, size_t n)
Definition mem_utils.cpp:24
void fe_sq2(FE_25519 &x, const FE_25519 &z)
Definition ed25519_fe.h:200
void fe_add(FE_25519 &x, const FE_25519 &a, const FE_25519 &b)
Definition ed25519_fe.h:176
void fe_sub(FE_25519 &x, const FE_25519 &a, const FE_25519 &b)
Definition ed25519_fe.h:180
int fe_isnegative(const FE_25519 &x)
Definition ed25519_fe.h:164
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:149
void fe_mul(FE_25519 &x, const FE_25519 &a, const FE_25519 &b)
Definition ed25519_fe.h:188
constexpr void clear_mem(T *ptr, size_t n)
Definition mem_ops.h:123
void fe_frombytes(FE_25519 &x, const uint8_t *b)
Definition ed25519_fe.h:148
void fe_neg(FE_25519 &x, const FE_25519 &z)
Definition ed25519_fe.h:184