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 1571732784 : fd_f25519_t const * b ) {
38 1571732784 : fiat_25519_carry_mul( r->el, a->el, b->el );
39 1571732784 : return r;
40 1571732784 : }
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 1494659838 : fd_f25519_t const * a ) {
46 1494659838 : fiat_25519_carry_square( r->el, a->el );
47 1494659838 : return r;
48 1494659838 : }
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 377858447 : fd_f25519_t const * b ) {
55 377858447 : fiat_25519_add( r->el, a->el, b->el );
56 377858447 : fiat_25519_carry( r->el, r->el );
57 377858447 : return r;
58 377858447 : }
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 152805701 : fd_f25519_t const * b ) {
65 152805701 : fiat_25519_sub( r->el, a->el, b->el );
66 152805701 : fiat_25519_carry( r->el, r->el );
67 152805701 : return r;
68 152805701 : }
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 833631317 : fd_f25519_t const * b ) {
77 833631317 : fiat_25519_add( r->el, a->el, b->el );
78 833631317 : return r;
79 833631317 : }
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 660122386 : fd_f25519_t const * b ) {
88 660122386 : fiat_25519_sub( r->el, a->el, b->el );
89 660122386 : return r;
90 660122386 : }
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 81034392 : fd_f25519_t const * a ) {
96 81034392 : fiat_25519_opp( r->el, a->el );
97 81034392 : return r;
98 81034392 : }
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 33479970 : fd_f25519_t const * a ) {
104 33479970 : fiat_25519_carry_scmul_121666( r->el, a->el );
105 33479970 : return r;
106 33479970 : }
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, according to RFC 8032. */
111 : FD_25519_INLINE fd_f25519_t *
112 : fd_f25519_frombytes( fd_f25519_t * r,
113 3534468 : uchar const buf[ 32 ] ) {
114 3534468 : fiat_25519_from_bytes( r->el, buf );
115 3534468 : return r;
116 3534468 : }
117 :
118 : /* fd_f25519_tobytes serializes a fd_f25519_t element a into
119 : a 32-byte buffer out, and returns out.
120 : out is in little endian form, according to RFC 8032. */
121 : FD_25519_INLINE uchar *
122 : fd_f25519_tobytes( uchar out[ 32 ],
123 8605476 : fd_f25519_t const * a ) {
124 8605476 : fiat_25519_to_bytes( out, a->el );
125 8605476 : return out;
126 8605476 : }
127 :
128 : /* fd_f25519_if sets r = a0 if cond, else r = a1, equivalent to:
129 : r = cond ? a0 : a1.
130 : Note: this is constant time. */
131 : FD_25519_INLINE fd_f25519_t *
132 : fd_f25519_if( fd_f25519_t * r,
133 : int const cond, /* 0, 1 */
134 : fd_f25519_t const * a0,
135 2032250932 : fd_f25519_t const * a1 ) {
136 2032250932 : fiat_25519_selectznz( r->el, (uchar)cond, a1->el, a0->el );
137 2032250932 : return r;
138 2032250932 : }
139 :
140 : /* fd_f25519_swap_if swaps r1, r2 if cond, else leave them as is.
141 : Note: this is constant time. */
142 : FD_25519_INLINE void
143 : fd_f25519_swap_if( fd_f25519_t * restrict r1,
144 : fd_f25519_t * restrict r2,
145 67222528 : int const cond /* 0, 1 */ ) {
146 :
147 : #if USE_FIAT_32
148 : uint m = (uint)-!!cond;
149 : uint h0 = m & (r1->el[0] ^ r2->el[0]);
150 : uint h1 = m & (r1->el[1] ^ r2->el[1]);
151 : uint h2 = m & (r1->el[2] ^ r2->el[2]);
152 : uint h3 = m & (r1->el[3] ^ r2->el[3]);
153 : uint h4 = m & (r1->el[4] ^ r2->el[4]);
154 : uint h5 = m & (r1->el[5] ^ r2->el[5]);
155 : uint h6 = m & (r1->el[6] ^ r2->el[6]);
156 : uint h7 = m & (r1->el[7] ^ r2->el[7]);
157 : uint h8 = m & (r1->el[8] ^ r2->el[8]);
158 : uint h9 = m & (r1->el[9] ^ r2->el[9]);
159 :
160 : #else
161 67222528 : ulong m = (ulong)-!!cond;
162 67222528 : ulong h0 = m & (r1->el[0] ^ r2->el[0]);
163 67222528 : ulong h1 = m & (r1->el[1] ^ r2->el[1]);
164 67222528 : ulong h2 = m & (r1->el[2] ^ r2->el[2]);
165 67222528 : ulong h3 = m & (r1->el[3] ^ r2->el[3]);
166 67222528 : ulong h4 = m & (r1->el[4] ^ r2->el[4]);
167 67222528 : #endif
168 :
169 67222528 : r1->el[0] ^= h0;
170 67222528 : r1->el[1] ^= h1;
171 67222528 : r1->el[2] ^= h2;
172 67222528 : r1->el[3] ^= h3;
173 67222528 : r1->el[4] ^= h4;
174 :
175 67222528 : r2->el[0] ^= h0;
176 67222528 : r2->el[1] ^= h1;
177 67222528 : r2->el[2] ^= h2;
178 67222528 : r2->el[3] ^= h3;
179 67222528 : r2->el[4] ^= h4;
180 :
181 : #if USE_FIAT_32
182 : r1->el[5] ^= h5;
183 : r1->el[6] ^= h6;
184 : r1->el[7] ^= h7;
185 : r1->el[8] ^= h8;
186 : r1->el[9] ^= h9;
187 :
188 : r2->el[5] ^= h5;
189 : r2->el[6] ^= h6;
190 : r2->el[7] ^= h7;
191 : r2->el[8] ^= h8;
192 : r2->el[9] ^= h9;
193 : #endif
194 67222528 : }
195 :
196 : /* fd_f25519_set copies r = a, and returns r. */
197 : FD_25519_INLINE fd_f25519_t *
198 : fd_f25519_set( fd_f25519_t * r,
199 339433654 : fd_f25519_t const * a ) {
200 339433654 : r->el[0] = a->el[0];
201 339433654 : r->el[1] = a->el[1];
202 339433654 : r->el[2] = a->el[2];
203 339433654 : r->el[3] = a->el[3];
204 339433654 : r->el[4] = a->el[4];
205 : #if USE_FIAT_32
206 : r->el[5] = a->el[5];
207 : r->el[6] = a->el[6];
208 : r->el[7] = a->el[7];
209 : r->el[8] = a->el[8];
210 : r->el[9] = a->el[9];
211 : #endif
212 339433654 : return r;
213 339433654 : }
214 :
215 : /* fd_f25519_is_zero returns 1 if a == 0, 0 otherwise. */
216 : FD_25519_INLINE int
217 10391264 : fd_f25519_is_zero( fd_f25519_t const * a ) {
218 : // fiat_25519_tight_field_element x;
219 : // fiat_25519_carry( x, a->el );
220 : #if USE_FIAT_32
221 : uint const * x = a->el;
222 : if(( x[0] == 0
223 : && x[1] == 0
224 : && x[2] == 0
225 : && x[3] == 0
226 : && x[4] == 0
227 : && x[5] == 0
228 : && x[6] == 0
229 : && x[7] == 0
230 : && x[8] == 0
231 : && x[9] == 0
232 : ) || (
233 : x[0] == 0x3ffffed
234 : && x[1] == 0x1ffffff
235 : && x[2] == 0x3ffffff
236 : && x[3] == 0x1ffffff
237 : && x[4] == 0x3ffffff
238 : && x[5] == 0x1ffffff
239 : && x[6] == 0x3ffffff
240 : && x[7] == 0x1ffffff
241 : && x[8] == 0x3ffffff
242 : && x[9] == 0x1ffffff
243 : )) {
244 : return 1;
245 : }
246 : #else
247 10391264 : ulong const * x = a->el;
248 10391264 : if(( x[0] == 0
249 10391264 : && x[1] == 0
250 10391264 : && x[2] == 0
251 10391264 : && x[3] == 0
252 10391264 : && x[4] == 0
253 10391264 : ) || (
254 10390724 : x[0] == 0x7ffffffffffed
255 10390724 : && x[1] == 0x7ffffffffffff
256 10390724 : && x[2] == 0x7ffffffffffff
257 10390724 : && x[3] == 0x7ffffffffffff
258 10390724 : && x[4] == 0x7ffffffffffff
259 10390724 : )) {
260 2100754 : return 1;
261 2100754 : }
262 8290510 : #endif
263 8290510 : return 0;
264 10391264 : }
265 :
266 : /*
267 : * Vectorized
268 : */
269 :
270 : /* fd_f25519_muln computes r_i = a_i * b_i */
271 : FD_25519_INLINE void
272 : fd_f25519_mul2( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
273 68193278 : fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2 ) {
274 68193278 : fd_f25519_mul( r1, a1, b1 );
275 68193278 : fd_f25519_mul( r2, a2, b2 );
276 68193278 : }
277 :
278 : FD_25519_INLINE void
279 : fd_f25519_mul3( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
280 : fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
281 230846156 : fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3 ) {
282 230846156 : fd_f25519_mul( r1, a1, b1 );
283 230846156 : fd_f25519_mul( r2, a2, b2 );
284 230846156 : fd_f25519_mul( r3, a3, b3 );
285 230846156 : }
286 :
287 : FD_25519_INLINE void
288 : fd_f25519_mul4( fd_f25519_t * r1, fd_f25519_t const * a1, fd_f25519_t const * b1,
289 : fd_f25519_t * r2, fd_f25519_t const * a2, fd_f25519_t const * b2,
290 : fd_f25519_t * r3, fd_f25519_t const * a3, fd_f25519_t const * b3,
291 160601261 : fd_f25519_t * r4, fd_f25519_t const * a4, fd_f25519_t const * b4 ) {
292 160601261 : fd_f25519_mul( r1, a1, b1 );
293 160601261 : fd_f25519_mul( r2, a2, b2 );
294 160601261 : fd_f25519_mul( r3, a3, b3 );
295 160601261 : fd_f25519_mul( r4, a4, b4 );
296 160601261 : }
297 :
298 : /* fd_f25519_sqrn computes r_i = a_i^2 */
299 : FD_25519_INLINE void
300 : fd_f25519_sqr2( fd_f25519_t * r1, fd_f25519_t const * a1,
301 33479970 : fd_f25519_t * r2, fd_f25519_t const * a2 ) {
302 33479970 : fd_f25519_sqr( r1, a1 );
303 33479970 : fd_f25519_sqr( r2, a2 );
304 33479970 : }
305 :
306 : FD_25519_INLINE void
307 : fd_f25519_sqr3( fd_f25519_t * r1, fd_f25519_t const * a1,
308 : fd_f25519_t * r2, fd_f25519_t const * a2,
309 0 : fd_f25519_t * r3, fd_f25519_t const * a3 ) {
310 0 : fd_f25519_sqr( r1, a1 );
311 0 : fd_f25519_sqr( r2, a2 );
312 0 : fd_f25519_sqr( r3, a3 );
313 0 : }
314 :
315 : FD_25519_INLINE void
316 : fd_f25519_sqr4( fd_f25519_t * r1, fd_f25519_t const * a1,
317 : fd_f25519_t * r2, fd_f25519_t const * a2,
318 : fd_f25519_t * r3, fd_f25519_t const * a3,
319 140703691 : fd_f25519_t * r4, fd_f25519_t const * a4 ) {
320 140703691 : fd_f25519_sqr( r1, a1 );
321 140703691 : fd_f25519_sqr( r2, a2 );
322 140703691 : fd_f25519_sqr( r3, a3 );
323 140703691 : fd_f25519_sqr( r4, a4 );
324 140703691 : }
325 :
326 : FD_PROTOTYPES_END
|