Line data Source code
1 : #ifndef HEADER_fd_src_ballet_ed25519_fd_f25519_h
2 : #error "Do not include this directly; use fd_f25519.h"
3 : #endif
4 :
5 : #include "../../fd_ballet_base.h"
6 :
7 : #define USE_FIAT_32 0
8 : #if USE_FIAT_32
9 : #include "../../fiat-crypto/curve25519_32.c"
10 : #else
11 : #include "../../fiat-crypto/curve25519_64.c"
12 : #endif
13 :
14 : /* A fd_f25519_t stores a curve25519 field element in 10 uint (32 bit),
15 : or 5 ulong (64 bit). */
16 : struct fd_f25519 {
17 : #if USE_FIAT_32
18 : uint el[10];
19 : #else
20 : ulong el[5];
21 : #endif
22 : };
23 : typedef struct fd_f25519 fd_f25519_t;
24 :
25 : #include "../table/fd_f25519_table_ref.c"
26 :
27 : FD_PROTOTYPES_BEGIN
28 :
29 : /*
30 : * Implementation of inline functions
31 : */
32 :
33 : /* fd_f25519_mul computes r = a * b, and returns r. */
34 : FD_25519_INLINE fd_f25519_t *
35 : fd_f25519_mul( fd_f25519_t * r,
36 : fd_f25519_t const * a,
37 1541820143 : fd_f25519_t const * b ) {
38 1541820143 : fiat_25519_carry_mul( r->el, a->el, b->el );
39 1541820143 : return r;
40 1541820143 : }
41 :
42 : /* fd_f25519_sqr computes r = a^2, and returns r. */
43 : FD_25519_INLINE fd_f25519_t *
44 : fd_f25519_sqr( fd_f25519_t * r,
45 1480431104 : fd_f25519_t const * a ) {
46 1480431104 : fiat_25519_carry_square( r->el, a->el );
47 1480431104 : return r;
48 1480431104 : }
49 :
50 : /* fd_f25519_add computes r = a + b, and returns r. */
51 : FD_25519_INLINE fd_f25519_t *
52 : fd_f25519_add( fd_f25519_t * r,
53 : fd_f25519_t const * a,
54 373877743 : fd_f25519_t const * b ) {
55 373877743 : fiat_25519_add( r->el, a->el, b->el );
56 373877743 : fiat_25519_carry( r->el, r->el );
57 373877743 : return r;
58 373877743 : }
59 :
60 : /* fd_f25519_add computes r = a - b, and returns r. */
61 : FD_25519_INLINE fd_f25519_t *
62 : fd_f25519_sub( fd_f25519_t * r,
63 : fd_f25519_t const * a,
64 151956190 : fd_f25519_t const * b ) {
65 151956190 : fiat_25519_sub( r->el, a->el, b->el );
66 151956190 : fiat_25519_carry( r->el, r->el );
67 151956190 : return r;
68 151956190 : }
69 :
70 : /* fd_f25519_add computes r = a + b, and returns r.
71 : Note: this does NOT reduce the result mod p.
72 : It can be used before mul, sqr. */
73 : FD_25519_INLINE fd_f25519_t *
74 : fd_f25519_add_nr( fd_f25519_t * r,
75 : fd_f25519_t const * a,
76 819794197 : fd_f25519_t const * b ) {
77 819794197 : fiat_25519_add( r->el, a->el, b->el );
78 819794197 : return r;
79 819794197 : }
80 :
81 : /* fd_f25519_sub computes r = a - b, and returns r.
82 : Note: this does NOT reduce the result mod p.
83 : It can be used before mul, sqr. */
84 : FD_25519_INLINE fd_f25519_t *
85 : fd_f25519_sub_nr( fd_f25519_t * r,
86 : fd_f25519_t const * a,
87 648326468 : fd_f25519_t const * b ) {
88 648326468 : fiat_25519_sub( r->el, a->el, b->el );
89 648326468 : return r;
90 648326468 : }
91 :
92 : /* fd_f25519_add computes r = -a, and returns r. */
93 : FD_25519_INLINE fd_f25519_t *
94 : fd_f25519_neg( fd_f25519_t * r,
95 78839363 : fd_f25519_t const * a ) {
96 78839363 : fiat_25519_opp( r->el, a->el );
97 78839363 : return r;
98 78839363 : }
99 :
100 : /* fd_f25519_add computes r = a * k, k=121666, and returns r. */
101 : FD_25519_INLINE fd_f25519_t *
102 : fd_f25519_mul_121666( fd_f25519_t * r,
103 33518730 : fd_f25519_t const * a ) {
104 33518730 : fiat_25519_carry_scmul_121666( r->el, a->el );
105 33518730 : return r;
106 33518730 : }
107 :
108 : /* fd_f25519_frombytes deserializes a 32-byte buffer buf into a
109 : fd_f25519_t element r, and returns r.
110 : buf is in little endian form, we accept non-canonical elements
111 : unlike RFC 8032. */
112 : FD_25519_INLINE fd_f25519_t *
113 : fd_f25519_frombytes( fd_f25519_t * r,
114 3524052 : uchar const buf[ 32 ] ) {
115 3524052 : fiat_25519_from_bytes( r->el, buf );
116 3524052 : return r;
117 3524052 : }
118 :
119 : /* fd_f25519_tobytes serializes a fd_f25519_t element a into
120 : a 32-byte buffer out, and returns out.
121 : out is in little endian form, according to RFC 8032
122 : (we don't output non-canonical elements). */
123 : FD_25519_INLINE uchar *
124 : fd_f25519_tobytes( uchar out[ 32 ],
125 8508934 : fd_f25519_t const * a ) {
126 8508934 : fiat_25519_to_bytes( out, a->el );
127 8508934 : return out;
128 8508934 : }
129 :
130 : /* fd_f25519_if sets r = a0 if cond, else r = a1, equivalent to:
131 : r = cond ? a0 : a1.
132 : Note: this is constant time. */
133 : FD_25519_INLINE fd_f25519_t *
134 : fd_f25519_if( fd_f25519_t * r,
135 : int const cond, /* 0, 1 */
136 : fd_f25519_t const * a0,
137 1973943634 : fd_f25519_t const * a1 ) {
138 1973943634 : fiat_25519_selectznz( r->el, (uchar)cond, a1->el, a0->el );
139 1973943634 : return r;
140 1973943634 : }
141 :
142 : /* fd_f25519_swap_if swaps r1, r2 if cond, else leave them as is.
143 : Note: this is constant time. */
144 : FD_25519_INLINE void
145 : fd_f25519_swap_if( fd_f25519_t * restrict r1,
146 : fd_f25519_t * restrict r2,
147 67300352 : int const cond /* 0, 1 */ ) {
148 :
149 : #if USE_FIAT_32
150 : uint m = (uint)-!!cond;
151 : uint h0 = m & (r1->el[0] ^ r2->el[0]);
152 : uint h1 = m & (r1->el[1] ^ r2->el[1]);
153 : uint h2 = m & (r1->el[2] ^ r2->el[2]);
154 : uint h3 = m & (r1->el[3] ^ r2->el[3]);
155 : uint h4 = m & (r1->el[4] ^ r2->el[4]);
156 : uint h5 = m & (r1->el[5] ^ r2->el[5]);
157 : uint h6 = m & (r1->el[6] ^ r2->el[6]);
158 : uint h7 = m & (r1->el[7] ^ r2->el[7]);
159 : uint h8 = m & (r1->el[8] ^ r2->el[8]);
160 : uint h9 = m & (r1->el[9] ^ r2->el[9]);
161 :
162 : #else
163 67300352 : ulong m = (ulong)-!!cond;
164 67300352 : ulong h0 = m & (r1->el[0] ^ r2->el[0]);
165 67300352 : ulong h1 = m & (r1->el[1] ^ r2->el[1]);
166 67300352 : ulong h2 = m & (r1->el[2] ^ r2->el[2]);
167 67300352 : ulong h3 = m & (r1->el[3] ^ r2->el[3]);
168 67300352 : ulong h4 = m & (r1->el[4] ^ r2->el[4]);
169 67300352 : #endif
170 :
171 67300352 : r1->el[0] ^= h0;
172 67300352 : r1->el[1] ^= h1;
173 67300352 : r1->el[2] ^= h2;
174 67300352 : r1->el[3] ^= h3;
175 67300352 : r1->el[4] ^= h4;
176 :
177 67300352 : r2->el[0] ^= h0;
178 67300352 : r2->el[1] ^= h1;
179 67300352 : r2->el[2] ^= h2;
180 67300352 : r2->el[3] ^= h3;
181 67300352 : r2->el[4] ^= h4;
182 :
183 : #if USE_FIAT_32
184 : r1->el[5] ^= h5;
185 : r1->el[6] ^= h6;
186 : r1->el[7] ^= h7;
187 : r1->el[8] ^= h8;
188 : r1->el[9] ^= h9;
189 :
190 : r2->el[5] ^= h5;
191 : r2->el[6] ^= h6;
192 : r2->el[7] ^= h7;
193 : r2->el[8] ^= h8;
194 : r2->el[9] ^= h9;
195 : #endif
196 67300352 : }
197 :
198 : /* fd_f25519_set copies r = a, and returns r. */
199 : FD_25519_INLINE fd_f25519_t *
200 : fd_f25519_set( fd_f25519_t * r,
201 329860498 : fd_f25519_t const * a ) {
202 329860498 : r->el[0] = a->el[0];
203 329860498 : r->el[1] = a->el[1];
204 329860498 : r->el[2] = a->el[2];
205 329860498 : r->el[3] = a->el[3];
206 329860498 : r->el[4] = a->el[4];
207 : #if USE_FIAT_32
208 : r->el[5] = a->el[5];
209 : r->el[6] = a->el[6];
210 : r->el[7] = a->el[7];
211 : r->el[8] = a->el[8];
212 : r->el[9] = a->el[9];
213 : #endif
214 329860498 : return r;
215 329860498 : }
216 :
217 : /* fd_f25519_is_zero returns 1 if a == 0, 0 otherwise. */
218 : FD_25519_INLINE int
219 10332206 : fd_f25519_is_zero( fd_f25519_t const * a ) {
220 : // fiat_25519_tight_field_element x;
221 : // fiat_25519_carry( x, a->el );
222 : #if USE_FIAT_32
223 : uint const * x = a->el;
224 : if(( x[0] == 0
225 : && x[1] == 0
226 : && x[2] == 0
227 : && x[3] == 0
228 : && x[4] == 0
229 : && x[5] == 0
230 : && x[6] == 0
231 : && x[7] == 0
232 : && x[8] == 0
233 : && x[9] == 0
234 : ) || (
235 : x[0] == 0x3ffffed
236 : && x[1] == 0x1ffffff
237 : && x[2] == 0x3ffffff
238 : && x[3] == 0x1ffffff
239 : && x[4] == 0x3ffffff
240 : && x[5] == 0x1ffffff
241 : && x[6] == 0x3ffffff
242 : && x[7] == 0x1ffffff
243 : && x[8] == 0x3ffffff
244 : && x[9] == 0x1ffffff
245 : )) {
246 : return 1;
247 : }
248 : #else
249 10332206 : ulong const * x = a->el;
250 10332206 : if(( x[0] == 0
251 10332206 : && x[1] == 0
252 10332206 : && x[2] == 0
253 10332206 : && x[3] == 0
254 10332206 : && x[4] == 0
255 10332206 : ) || (
256 10331876 : x[0] == 0x7ffffffffffed
257 10331876 : && x[1] == 0x7ffffffffffff
258 10331876 : && x[2] == 0x7ffffffffffff
259 10331876 : && x[3] == 0x7ffffffffffff
260 10331876 : && x[4] == 0x7ffffffffffff
261 10331876 : )) {
262 2084396 : return 1;
263 2084396 : }
264 8247810 : #endif
265 8247810 : return 0;
266 10332206 : }
267 :
268 : /*
269 : * Vectorized
270 : */
271 :
272 : /* fd_f25519_muln computes r_i = a_i * b_i */
273 : FD_25519_INLINE void
274 : fd_f25519_mul2( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
275 68237060 : fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2 ) {
276 68237060 : fd_f25519_mul( r1, a1, b1 );
277 68237060 : fd_f25519_mul( r2, a2, b2 );
278 68237060 : }
279 :
280 : FD_25519_INLINE void
281 : fd_f25519_mul3( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
282 : fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
283 227731145 : fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3 ) {
284 227731145 : fd_f25519_mul( r1, a1, b1 );
285 227731145 : fd_f25519_mul( r2, a2, b2 );
286 227731145 : fd_f25519_mul( r3, a3, b3 );
287 227731145 : }
288 :
289 : FD_25519_INLINE void
290 : fd_f25519_mul4( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
291 : fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
292 : fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3,
293 155642481 : fd_f25519_t * r4, fd_f25519_t const * a4, fd_f25519_t const * b4 ) {
294 155642481 : fd_f25519_mul( r1, a1, b1 );
295 155642481 : fd_f25519_mul( r2, a2, b2 );
296 155642481 : fd_f25519_mul( r3, a3, b3 );
297 155642481 : fd_f25519_mul( r4, a4, b4 );
298 155642481 : }
299 :
300 : /* fd_f25519_sqrn computes r_i = a_i^2 */
301 : FD_25519_INLINE void
302 : fd_f25519_sqr2( fd_f25519_t * r1, fd_f25519_t const * a1,
303 33518730 : fd_f25519_t * r2, fd_f25519_t const * a2 ) {
304 33518730 : fd_f25519_sqr( r1, a1 );
305 33518730 : fd_f25519_sqr( r2, a2 );
306 33518730 : }
307 :
308 : FD_25519_INLINE void
309 : fd_f25519_sqr3( fd_f25519_t * r1, fd_f25519_t const * a1,
310 : fd_f25519_t * r2, fd_f25519_t const * a2,
311 0 : fd_f25519_t * r3, fd_f25519_t const * a3 ) {
312 0 : fd_f25519_sqr( r1, a1 );
313 0 : fd_f25519_sqr( r2, a2 );
314 0 : fd_f25519_sqr( r3, a3 );
315 0 : }
316 :
317 : FD_25519_INLINE void
318 : fd_f25519_sqr4( fd_f25519_t * r1, fd_f25519_t const * a1,
319 : fd_f25519_t * r2, fd_f25519_t const * a2,
320 : fd_f25519_t * r3, fd_f25519_t const * a3,
321 139913838 : fd_f25519_t * r4, fd_f25519_t const * a4 ) {
322 139913838 : fd_f25519_sqr( r1, a1 );
323 139913838 : fd_f25519_sqr( r2, a2 );
324 139913838 : fd_f25519_sqr( r3, a3 );
325 139913838 : fd_f25519_sqr( r4, a4 );
326 139913838 : }
327 :
328 : FD_PROTOTYPES_END
|