ed25519 1.2.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +12 -5
  3. data/README.md +2 -2
  4. data/ed25519.gemspec +1 -1
  5. data/ext/ed25519_ref10/fe.c +1085 -0
  6. data/ext/ed25519_ref10/ge.c +407 -0
  7. data/lib/ed25519/version.rb +1 -1
  8. metadata +4 -36
  9. data/ext/ed25519_ref10/fe_0.c +0 -19
  10. data/ext/ed25519_ref10/fe_1.c +0 -19
  11. data/ext/ed25519_ref10/fe_add.c +0 -57
  12. data/ext/ed25519_ref10/fe_cmov.c +0 -63
  13. data/ext/ed25519_ref10/fe_copy.c +0 -29
  14. data/ext/ed25519_ref10/fe_frombytes.c +0 -71
  15. data/ext/ed25519_ref10/fe_invert.c +0 -14
  16. data/ext/ed25519_ref10/fe_isnegative.c +0 -16
  17. data/ext/ed25519_ref10/fe_isnonzero.c +0 -19
  18. data/ext/ed25519_ref10/fe_mul.c +0 -252
  19. data/ext/ed25519_ref10/fe_neg.c +0 -45
  20. data/ext/ed25519_ref10/fe_pow22523.c +0 -13
  21. data/ext/ed25519_ref10/fe_sq.c +0 -148
  22. data/ext/ed25519_ref10/fe_sq2.c +0 -159
  23. data/ext/ed25519_ref10/fe_sub.c +0 -57
  24. data/ext/ed25519_ref10/fe_tobytes.c +0 -119
  25. data/ext/ed25519_ref10/ge_add.c +0 -11
  26. data/ext/ed25519_ref10/ge_double_scalarmult.c +0 -96
  27. data/ext/ed25519_ref10/ge_frombytes.c +0 -50
  28. data/ext/ed25519_ref10/ge_madd.c +0 -11
  29. data/ext/ed25519_ref10/ge_msub.c +0 -11
  30. data/ext/ed25519_ref10/ge_p1p1_to_p2.c +0 -12
  31. data/ext/ed25519_ref10/ge_p1p1_to_p3.c +0 -13
  32. data/ext/ed25519_ref10/ge_p2_0.c +0 -8
  33. data/ext/ed25519_ref10/ge_p2_dbl.c +0 -11
  34. data/ext/ed25519_ref10/ge_p3_0.c +0 -9
  35. data/ext/ed25519_ref10/ge_p3_dbl.c +0 -12
  36. data/ext/ed25519_ref10/ge_p3_to_cached.c +0 -17
  37. data/ext/ed25519_ref10/ge_p3_to_p2.c +0 -12
  38. data/ext/ed25519_ref10/ge_p3_tobytes.c +0 -14
  39. data/ext/ed25519_ref10/ge_precomp_0.c +0 -8
  40. data/ext/ed25519_ref10/ge_scalarmult_base.c +0 -104
  41. data/ext/ed25519_ref10/ge_sub.c +0 -11
  42. data/ext/ed25519_ref10/ge_tobytes.c +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e51b8abba36131f62270b9dfff5c9ba75346893e56dc7b271a1ef0eabd4127bb
4
- data.tar.gz: 238daf803781b19a821b9581eee70ef81594b47faee8972ab1f321907af208bd
3
+ metadata.gz: 6173c3a29df4b71fea845289dc18dc9626ef7c45f361dd6599fc3a0d380f1641
4
+ data.tar.gz: 7c502be6a6c84b17b6755ba61da9fbf380d13905d89d407a470f9129194cff5c
5
5
  SHA512:
6
- metadata.gz: a39e5705fe433efeaab6048a8a2b414c2732d3982eee22262a381891efc5272ea3059d837535294c0f50cb81df4deaae9f7cf4ecc26bb9dcd23f628f52339e3d
7
- data.tar.gz: fd3b2a89b7fc7441ca189bc17f62db4104a7702ff8618b74721bbb44e878c3081a4fc45b406aba138ad14f9505863a7379a4f5ab2f4f94727e5a824ff89f495b
6
+ metadata.gz: c7f72a79e4872f809309740007e65e900aa8b0b2e959738d0d7a62fcfefd364a29f06f4a3ff92b41db14bb8995ca0d4b2d45f448004b63cf0a4cc865b16d6281
7
+ data.tar.gz: 5499bc94c84e1a1d9507ff42db18dade50f61915aff05e0510105360e30b821d14bf96bf6426f2c5a43f7bc3134712bb4f069207ad8e2f578179960746f0b2e9
data/CHANGES.md CHANGED
@@ -1,4 +1,11 @@
1
- # [1.2.2] (2017-12-31)
1
+ ## [1.2.3] (2017-12-31)
2
+
3
+ [1.2.3]: https://github.com/crypto-rb/ed25519/compare/v1.2.2...v1.2.3
4
+
5
+ * [#18](https://github.com/crypto-rb/ed25519/pull/18)
6
+ `ext/ed25519_ref10`: Consolidate fe.c and ge.c
7
+
8
+ ## [1.2.2] (2017-12-31)
2
9
 
3
10
  [1.2.2]: https://github.com/crypto-rb/ed25519/compare/v1.2.1...v1.2.2
4
11
 
@@ -8,14 +15,14 @@
8
15
  * [#16](https://github.com/crypto-rb/ed25519/pull/16)
9
16
  Move project to the crypto-rb GitHub organization
10
17
 
11
- # [1.2.1] (2017-12-15)
18
+ ## [1.2.1] (2017-12-15)
12
19
 
13
20
  [1.2.1]: https://github.com/crypto-rb/ed25519/compare/v1.2.0...v1.2.1
14
21
 
15
22
  * [#14](https://github.com/crypto-rb/ed25519/pull/14)
16
23
  Support MRI 2.0+
17
24
 
18
- # [1.2.0] (2017-12-15)
25
+ ## [1.2.0] (2017-12-15)
19
26
 
20
27
  [1.2.0]: https://github.com/crypto-rb/ed25519/compare/v1.1.0...v1.2.0
21
28
 
@@ -25,7 +32,7 @@
25
32
  * [#12](https://github.com/crypto-rb/ed25519/pull/12)
26
33
  Add `Ed25519.validate_key_bytes` method
27
34
 
28
- # [1.1.0] (2017-12-13)
35
+ ## [1.1.0] (2017-12-13)
29
36
 
30
37
  [1.1.0]: https://github.com/crypto-rb/ed25519/compare/v1.0.0...v1.1.0
31
38
 
@@ -38,7 +45,7 @@
38
45
  * [#8](https://github.com/crypto-rb/ed25519/pull/8)
39
46
  Use an attr_accessor for Ed25519.provider
40
47
 
41
- # [1.0.0] (2017-12-12)
48
+ ## [1.0.0] (2017-12-12)
42
49
 
43
50
  [1.0.0]: https://github.com/crypto-rb/ed25519/compare/v0.1.0...v1.0.0
44
51
 
data/README.md CHANGED
@@ -4,10 +4,10 @@
4
4
  [gem-link]: https://rubygems.org/gems/ed25519
5
5
  [build-image]: https://travis-ci.org/crypto-rb/ed25519.svg?branch=master
6
6
  [build-link]: https://travis-ci.org/crypto-rb/ed25519
7
- [appveyor-image]: https://ci.appveyor.com/api/projects/status/vvhin6cb9ux97nqu?svg=true
7
+ [appveyor-image]: https://ci.appveyor.com/api/projects/status/4s05bcae0mow85v1?svg=true
8
8
  [appveyor-link]: https://ci.appveyor.com/project/tarcieri/ed25519
9
9
  [docs-image]: https://img.shields.io/badge/yard-docs-blue.svg
10
- [docs-link]: http://www.rubydoc.info/gems/ed25519/1.2.1
10
+ [docs-link]: http://www.rubydoc.info/gems/ed25519/1.2.3
11
11
  [license-image]: https://img.shields.io/badge/license-MIT-blue.svg
12
12
  [license-link]: https://github.com/crypto-rb/ed25519/blob/master/LICENSE
13
13
 
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  if defined? JRUBY_VERSION
22
22
  spec.platform = "jruby"
23
- spec.files << "lib/ed25519_java.jar"
23
+ spec.files << "lib/ed25519_jruby.jar"
24
24
  else
25
25
  spec.platform = Gem::Platform::RUBY
26
26
  spec.extensions = ["ext/ed25519_ref10/extconf.rb"]
@@ -0,0 +1,1085 @@
1
+ #include "fe.h"
2
+ #include "ed25519_ref10.h"
3
+
4
+ /*
5
+ h = 0
6
+ */
7
+
8
+ void fe_0(fe h)
9
+ {
10
+ h[0] = 0;
11
+ h[1] = 0;
12
+ h[2] = 0;
13
+ h[3] = 0;
14
+ h[4] = 0;
15
+ h[5] = 0;
16
+ h[6] = 0;
17
+ h[7] = 0;
18
+ h[8] = 0;
19
+ h[9] = 0;
20
+ }
21
+
22
+ /*
23
+ h = 1
24
+ */
25
+
26
+ void fe_1(fe h)
27
+ {
28
+ h[0] = 1;
29
+ h[1] = 0;
30
+ h[2] = 0;
31
+ h[3] = 0;
32
+ h[4] = 0;
33
+ h[5] = 0;
34
+ h[6] = 0;
35
+ h[7] = 0;
36
+ h[8] = 0;
37
+ h[9] = 0;
38
+ }
39
+
40
+ /*
41
+ h = f + g
42
+ Can overlap h with f or g.
43
+
44
+ Preconditions:
45
+ |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
46
+ |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
47
+
48
+ Postconditions:
49
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
50
+ */
51
+
52
+ void fe_add(fe h,const fe f,const fe g)
53
+ {
54
+ int32_t f0 = f[0];
55
+ int32_t f1 = f[1];
56
+ int32_t f2 = f[2];
57
+ int32_t f3 = f[3];
58
+ int32_t f4 = f[4];
59
+ int32_t f5 = f[5];
60
+ int32_t f6 = f[6];
61
+ int32_t f7 = f[7];
62
+ int32_t f8 = f[8];
63
+ int32_t f9 = f[9];
64
+ int32_t g0 = g[0];
65
+ int32_t g1 = g[1];
66
+ int32_t g2 = g[2];
67
+ int32_t g3 = g[3];
68
+ int32_t g4 = g[4];
69
+ int32_t g5 = g[5];
70
+ int32_t g6 = g[6];
71
+ int32_t g7 = g[7];
72
+ int32_t g8 = g[8];
73
+ int32_t g9 = g[9];
74
+ int32_t h0 = f0 + g0;
75
+ int32_t h1 = f1 + g1;
76
+ int32_t h2 = f2 + g2;
77
+ int32_t h3 = f3 + g3;
78
+ int32_t h4 = f4 + g4;
79
+ int32_t h5 = f5 + g5;
80
+ int32_t h6 = f6 + g6;
81
+ int32_t h7 = f7 + g7;
82
+ int32_t h8 = f8 + g8;
83
+ int32_t h9 = f9 + g9;
84
+ h[0] = h0;
85
+ h[1] = h1;
86
+ h[2] = h2;
87
+ h[3] = h3;
88
+ h[4] = h4;
89
+ h[5] = h5;
90
+ h[6] = h6;
91
+ h[7] = h7;
92
+ h[8] = h8;
93
+ h[9] = h9;
94
+ }
95
+
96
+ /*
97
+ Replace (f,g) with (g,g) if b == 1;
98
+ replace (f,g) with (f,g) if b == 0.
99
+
100
+ Preconditions: b in {0,1}.
101
+ */
102
+
103
+ void fe_cmov(fe f,const fe g,unsigned int b)
104
+ {
105
+ int32_t f0 = f[0];
106
+ int32_t f1 = f[1];
107
+ int32_t f2 = f[2];
108
+ int32_t f3 = f[3];
109
+ int32_t f4 = f[4];
110
+ int32_t f5 = f[5];
111
+ int32_t f6 = f[6];
112
+ int32_t f7 = f[7];
113
+ int32_t f8 = f[8];
114
+ int32_t f9 = f[9];
115
+ int32_t g0 = g[0];
116
+ int32_t g1 = g[1];
117
+ int32_t g2 = g[2];
118
+ int32_t g3 = g[3];
119
+ int32_t g4 = g[4];
120
+ int32_t g5 = g[5];
121
+ int32_t g6 = g[6];
122
+ int32_t g7 = g[7];
123
+ int32_t g8 = g[8];
124
+ int32_t g9 = g[9];
125
+ int32_t x0 = f0 ^ g0;
126
+ int32_t x1 = f1 ^ g1;
127
+ int32_t x2 = f2 ^ g2;
128
+ int32_t x3 = f3 ^ g3;
129
+ int32_t x4 = f4 ^ g4;
130
+ int32_t x5 = f5 ^ g5;
131
+ int32_t x6 = f6 ^ g6;
132
+ int32_t x7 = f7 ^ g7;
133
+ int32_t x8 = f8 ^ g8;
134
+ int32_t x9 = f9 ^ g9;
135
+ b = -b;
136
+ x0 &= b;
137
+ x1 &= b;
138
+ x2 &= b;
139
+ x3 &= b;
140
+ x4 &= b;
141
+ x5 &= b;
142
+ x6 &= b;
143
+ x7 &= b;
144
+ x8 &= b;
145
+ x9 &= b;
146
+ f[0] = f0 ^ x0;
147
+ f[1] = f1 ^ x1;
148
+ f[2] = f2 ^ x2;
149
+ f[3] = f3 ^ x3;
150
+ f[4] = f4 ^ x4;
151
+ f[5] = f5 ^ x5;
152
+ f[6] = f6 ^ x6;
153
+ f[7] = f7 ^ x7;
154
+ f[8] = f8 ^ x8;
155
+ f[9] = f9 ^ x9;
156
+ }
157
+
158
+ /*
159
+ h = f
160
+ */
161
+
162
+ void fe_copy(fe h,const fe f)
163
+ {
164
+ int32_t f0 = f[0];
165
+ int32_t f1 = f[1];
166
+ int32_t f2 = f[2];
167
+ int32_t f3 = f[3];
168
+ int32_t f4 = f[4];
169
+ int32_t f5 = f[5];
170
+ int32_t f6 = f[6];
171
+ int32_t f7 = f[7];
172
+ int32_t f8 = f[8];
173
+ int32_t f9 = f[9];
174
+ h[0] = f0;
175
+ h[1] = f1;
176
+ h[2] = f2;
177
+ h[3] = f3;
178
+ h[4] = f4;
179
+ h[5] = f5;
180
+ h[6] = f6;
181
+ h[7] = f7;
182
+ h[8] = f8;
183
+ h[9] = f9;
184
+ }
185
+
186
+ static uint64_t load_3(const unsigned char *in)
187
+ {
188
+ uint64_t result;
189
+ result = (uint64_t) in[0];
190
+ result |= ((uint64_t) in[1]) << 8;
191
+ result |= ((uint64_t) in[2]) << 16;
192
+ return result;
193
+ }
194
+
195
+ static uint64_t load_4(const unsigned char *in)
196
+ {
197
+ uint64_t result;
198
+ result = (uint64_t) in[0];
199
+ result |= ((uint64_t) in[1]) << 8;
200
+ result |= ((uint64_t) in[2]) << 16;
201
+ result |= ((uint64_t) in[3]) << 24;
202
+ return result;
203
+ }
204
+
205
+ /*
206
+ Ignores top bit of h.
207
+ */
208
+
209
+ void fe_frombytes(fe h,const unsigned char *s)
210
+ {
211
+ int64_t h0 = load_4(s);
212
+ int64_t h1 = load_3(s + 4) << 6;
213
+ int64_t h2 = load_3(s + 7) << 5;
214
+ int64_t h3 = load_3(s + 10) << 3;
215
+ int64_t h4 = load_3(s + 13) << 2;
216
+ int64_t h5 = load_4(s + 16);
217
+ int64_t h6 = load_3(s + 20) << 7;
218
+ int64_t h7 = load_3(s + 23) << 5;
219
+ int64_t h8 = load_3(s + 26) << 4;
220
+ int64_t h9 = (load_3(s + 29) & 8388607) << 2;
221
+ int64_t carry0;
222
+ int64_t carry1;
223
+ int64_t carry2;
224
+ int64_t carry3;
225
+ int64_t carry4;
226
+ int64_t carry5;
227
+ int64_t carry6;
228
+ int64_t carry7;
229
+ int64_t carry8;
230
+ int64_t carry9;
231
+
232
+ carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
233
+ carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
234
+ carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
235
+ carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
236
+ carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
237
+
238
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
239
+ carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
240
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
241
+ carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
242
+ carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
243
+
244
+ h[0] = (int32_t)h0;
245
+ h[1] = (int32_t)h1;
246
+ h[2] = (int32_t)h2;
247
+ h[3] = (int32_t)h3;
248
+ h[4] = (int32_t)h4;
249
+ h[5] = (int32_t)h5;
250
+ h[6] = (int32_t)h6;
251
+ h[7] = (int32_t)h7;
252
+ h[8] = (int32_t)h8;
253
+ h[9] = (int32_t)h9;
254
+ }
255
+
256
+ void fe_invert(fe out,const fe z)
257
+ {
258
+ fe t0;
259
+ fe t1;
260
+ fe t2;
261
+ fe t3;
262
+ int i;
263
+
264
+ #include "pow225521.h"
265
+
266
+ return;
267
+ }
268
+
269
+ /*
270
+ return 1 if f is in {1,3,5,...,q-2}
271
+ return 0 if f is in {0,2,4,...,q-1}
272
+
273
+ Preconditions:
274
+ |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
275
+ */
276
+
277
+ int fe_isnegative(const fe f)
278
+ {
279
+ unsigned char s[32];
280
+ fe_tobytes(s,f);
281
+ return s[0] & 1;
282
+ }
283
+
284
+ /*
285
+ return 1 if f == 0
286
+ return 0 if f != 0
287
+
288
+ Preconditions:
289
+ |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
290
+ */
291
+
292
+ static const unsigned char zero[32];
293
+
294
+ int fe_isnonzero(const fe f)
295
+ {
296
+ unsigned char s[32];
297
+ fe_tobytes(s,f);
298
+ return crypto_verify_32(s,zero);
299
+ }
300
+
301
+ /*
302
+ h = f * g
303
+ Can overlap h with f or g.
304
+
305
+ Preconditions:
306
+ |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
307
+ |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
308
+
309
+ Postconditions:
310
+ |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
311
+ */
312
+
313
+ /*
314
+ Notes on implementation strategy:
315
+
316
+ Using schoolbook multiplication.
317
+ Karatsuba would save a little in some cost models.
318
+
319
+ Most multiplications by 2 and 19 are 32-bit precomputations;
320
+ cheaper than 64-bit postcomputations.
321
+
322
+ There is one remaining multiplication by 19 in the carry chain;
323
+ one *19 precomputation can be merged into this,
324
+ but the resulting data flow is considerably less clean.
325
+
326
+ There are 12 carries below.
327
+ 10 of them are 2-way parallelizable and vectorizable.
328
+ Can get away with 11 carries, but then data flow is much deeper.
329
+
330
+ With tighter constraints on inputs can squeeze carries into int32.
331
+ */
332
+
333
+ void fe_mul(fe h,const fe f,const fe g)
334
+ {
335
+ int32_t f0 = f[0];
336
+ int32_t f1 = f[1];
337
+ int32_t f2 = f[2];
338
+ int32_t f3 = f[3];
339
+ int32_t f4 = f[4];
340
+ int32_t f5 = f[5];
341
+ int32_t f6 = f[6];
342
+ int32_t f7 = f[7];
343
+ int32_t f8 = f[8];
344
+ int32_t f9 = f[9];
345
+ int32_t g0 = g[0];
346
+ int32_t g1 = g[1];
347
+ int32_t g2 = g[2];
348
+ int32_t g3 = g[3];
349
+ int32_t g4 = g[4];
350
+ int32_t g5 = g[5];
351
+ int32_t g6 = g[6];
352
+ int32_t g7 = g[7];
353
+ int32_t g8 = g[8];
354
+ int32_t g9 = g[9];
355
+ int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */
356
+ int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */
357
+ int32_t g3_19 = 19 * g3;
358
+ int32_t g4_19 = 19 * g4;
359
+ int32_t g5_19 = 19 * g5;
360
+ int32_t g6_19 = 19 * g6;
361
+ int32_t g7_19 = 19 * g7;
362
+ int32_t g8_19 = 19 * g8;
363
+ int32_t g9_19 = 19 * g9;
364
+ int32_t f1_2 = 2 * f1;
365
+ int32_t f3_2 = 2 * f3;
366
+ int32_t f5_2 = 2 * f5;
367
+ int32_t f7_2 = 2 * f7;
368
+ int32_t f9_2 = 2 * f9;
369
+ int64_t f0g0 = f0 * (int64_t) g0;
370
+ int64_t f0g1 = f0 * (int64_t) g1;
371
+ int64_t f0g2 = f0 * (int64_t) g2;
372
+ int64_t f0g3 = f0 * (int64_t) g3;
373
+ int64_t f0g4 = f0 * (int64_t) g4;
374
+ int64_t f0g5 = f0 * (int64_t) g5;
375
+ int64_t f0g6 = f0 * (int64_t) g6;
376
+ int64_t f0g7 = f0 * (int64_t) g7;
377
+ int64_t f0g8 = f0 * (int64_t) g8;
378
+ int64_t f0g9 = f0 * (int64_t) g9;
379
+ int64_t f1g0 = f1 * (int64_t) g0;
380
+ int64_t f1g1_2 = f1_2 * (int64_t) g1;
381
+ int64_t f1g2 = f1 * (int64_t) g2;
382
+ int64_t f1g3_2 = f1_2 * (int64_t) g3;
383
+ int64_t f1g4 = f1 * (int64_t) g4;
384
+ int64_t f1g5_2 = f1_2 * (int64_t) g5;
385
+ int64_t f1g6 = f1 * (int64_t) g6;
386
+ int64_t f1g7_2 = f1_2 * (int64_t) g7;
387
+ int64_t f1g8 = f1 * (int64_t) g8;
388
+ int64_t f1g9_38 = f1_2 * (int64_t) g9_19;
389
+ int64_t f2g0 = f2 * (int64_t) g0;
390
+ int64_t f2g1 = f2 * (int64_t) g1;
391
+ int64_t f2g2 = f2 * (int64_t) g2;
392
+ int64_t f2g3 = f2 * (int64_t) g3;
393
+ int64_t f2g4 = f2 * (int64_t) g4;
394
+ int64_t f2g5 = f2 * (int64_t) g5;
395
+ int64_t f2g6 = f2 * (int64_t) g6;
396
+ int64_t f2g7 = f2 * (int64_t) g7;
397
+ int64_t f2g8_19 = f2 * (int64_t) g8_19;
398
+ int64_t f2g9_19 = f2 * (int64_t) g9_19;
399
+ int64_t f3g0 = f3 * (int64_t) g0;
400
+ int64_t f3g1_2 = f3_2 * (int64_t) g1;
401
+ int64_t f3g2 = f3 * (int64_t) g2;
402
+ int64_t f3g3_2 = f3_2 * (int64_t) g3;
403
+ int64_t f3g4 = f3 * (int64_t) g4;
404
+ int64_t f3g5_2 = f3_2 * (int64_t) g5;
405
+ int64_t f3g6 = f3 * (int64_t) g6;
406
+ int64_t f3g7_38 = f3_2 * (int64_t) g7_19;
407
+ int64_t f3g8_19 = f3 * (int64_t) g8_19;
408
+ int64_t f3g9_38 = f3_2 * (int64_t) g9_19;
409
+ int64_t f4g0 = f4 * (int64_t) g0;
410
+ int64_t f4g1 = f4 * (int64_t) g1;
411
+ int64_t f4g2 = f4 * (int64_t) g2;
412
+ int64_t f4g3 = f4 * (int64_t) g3;
413
+ int64_t f4g4 = f4 * (int64_t) g4;
414
+ int64_t f4g5 = f4 * (int64_t) g5;
415
+ int64_t f4g6_19 = f4 * (int64_t) g6_19;
416
+ int64_t f4g7_19 = f4 * (int64_t) g7_19;
417
+ int64_t f4g8_19 = f4 * (int64_t) g8_19;
418
+ int64_t f4g9_19 = f4 * (int64_t) g9_19;
419
+ int64_t f5g0 = f5 * (int64_t) g0;
420
+ int64_t f5g1_2 = f5_2 * (int64_t) g1;
421
+ int64_t f5g2 = f5 * (int64_t) g2;
422
+ int64_t f5g3_2 = f5_2 * (int64_t) g3;
423
+ int64_t f5g4 = f5 * (int64_t) g4;
424
+ int64_t f5g5_38 = f5_2 * (int64_t) g5_19;
425
+ int64_t f5g6_19 = f5 * (int64_t) g6_19;
426
+ int64_t f5g7_38 = f5_2 * (int64_t) g7_19;
427
+ int64_t f5g8_19 = f5 * (int64_t) g8_19;
428
+ int64_t f5g9_38 = f5_2 * (int64_t) g9_19;
429
+ int64_t f6g0 = f6 * (int64_t) g0;
430
+ int64_t f6g1 = f6 * (int64_t) g1;
431
+ int64_t f6g2 = f6 * (int64_t) g2;
432
+ int64_t f6g3 = f6 * (int64_t) g3;
433
+ int64_t f6g4_19 = f6 * (int64_t) g4_19;
434
+ int64_t f6g5_19 = f6 * (int64_t) g5_19;
435
+ int64_t f6g6_19 = f6 * (int64_t) g6_19;
436
+ int64_t f6g7_19 = f6 * (int64_t) g7_19;
437
+ int64_t f6g8_19 = f6 * (int64_t) g8_19;
438
+ int64_t f6g9_19 = f6 * (int64_t) g9_19;
439
+ int64_t f7g0 = f7 * (int64_t) g0;
440
+ int64_t f7g1_2 = f7_2 * (int64_t) g1;
441
+ int64_t f7g2 = f7 * (int64_t) g2;
442
+ int64_t f7g3_38 = f7_2 * (int64_t) g3_19;
443
+ int64_t f7g4_19 = f7 * (int64_t) g4_19;
444
+ int64_t f7g5_38 = f7_2 * (int64_t) g5_19;
445
+ int64_t f7g6_19 = f7 * (int64_t) g6_19;
446
+ int64_t f7g7_38 = f7_2 * (int64_t) g7_19;
447
+ int64_t f7g8_19 = f7 * (int64_t) g8_19;
448
+ int64_t f7g9_38 = f7_2 * (int64_t) g9_19;
449
+ int64_t f8g0 = f8 * (int64_t) g0;
450
+ int64_t f8g1 = f8 * (int64_t) g1;
451
+ int64_t f8g2_19 = f8 * (int64_t) g2_19;
452
+ int64_t f8g3_19 = f8 * (int64_t) g3_19;
453
+ int64_t f8g4_19 = f8 * (int64_t) g4_19;
454
+ int64_t f8g5_19 = f8 * (int64_t) g5_19;
455
+ int64_t f8g6_19 = f8 * (int64_t) g6_19;
456
+ int64_t f8g7_19 = f8 * (int64_t) g7_19;
457
+ int64_t f8g8_19 = f8 * (int64_t) g8_19;
458
+ int64_t f8g9_19 = f8 * (int64_t) g9_19;
459
+ int64_t f9g0 = f9 * (int64_t) g0;
460
+ int64_t f9g1_38 = f9_2 * (int64_t) g1_19;
461
+ int64_t f9g2_19 = f9 * (int64_t) g2_19;
462
+ int64_t f9g3_38 = f9_2 * (int64_t) g3_19;
463
+ int64_t f9g4_19 = f9 * (int64_t) g4_19;
464
+ int64_t f9g5_38 = f9_2 * (int64_t) g5_19;
465
+ int64_t f9g6_19 = f9 * (int64_t) g6_19;
466
+ int64_t f9g7_38 = f9_2 * (int64_t) g7_19;
467
+ int64_t f9g8_19 = f9 * (int64_t) g8_19;
468
+ int64_t f9g9_38 = f9_2 * (int64_t) g9_19;
469
+ int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38;
470
+ int64_t h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19;
471
+ int64_t h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38;
472
+ int64_t h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19;
473
+ int64_t h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38;
474
+ int64_t h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19;
475
+ int64_t h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38;
476
+ int64_t h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19;
477
+ int64_t h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38;
478
+ int64_t h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ;
479
+ int64_t carry0;
480
+ int64_t carry1;
481
+ int64_t carry2;
482
+ int64_t carry3;
483
+ int64_t carry4;
484
+ int64_t carry5;
485
+ int64_t carry6;
486
+ int64_t carry7;
487
+ int64_t carry8;
488
+ int64_t carry9;
489
+
490
+ /*
491
+ |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38))
492
+ i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8
493
+ |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19))
494
+ i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9
495
+ */
496
+
497
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
498
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
499
+ /* |h0| <= 2^25 */
500
+ /* |h4| <= 2^25 */
501
+ /* |h1| <= 1.71*2^59 */
502
+ /* |h5| <= 1.71*2^59 */
503
+
504
+ carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
505
+ carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
506
+ /* |h1| <= 2^24; from now on fits into int32 */
507
+ /* |h5| <= 2^24; from now on fits into int32 */
508
+ /* |h2| <= 1.41*2^60 */
509
+ /* |h6| <= 1.41*2^60 */
510
+
511
+ carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
512
+ carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
513
+ /* |h2| <= 2^25; from now on fits into int32 unchanged */
514
+ /* |h6| <= 2^25; from now on fits into int32 unchanged */
515
+ /* |h3| <= 1.71*2^59 */
516
+ /* |h7| <= 1.71*2^59 */
517
+
518
+ carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
519
+ carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
520
+ /* |h3| <= 2^24; from now on fits into int32 unchanged */
521
+ /* |h7| <= 2^24; from now on fits into int32 unchanged */
522
+ /* |h4| <= 1.72*2^34 */
523
+ /* |h8| <= 1.41*2^60 */
524
+
525
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
526
+ carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
527
+ /* |h4| <= 2^25; from now on fits into int32 unchanged */
528
+ /* |h8| <= 2^25; from now on fits into int32 unchanged */
529
+ /* |h5| <= 1.01*2^24 */
530
+ /* |h9| <= 1.71*2^59 */
531
+
532
+ carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
533
+ /* |h9| <= 2^24; from now on fits into int32 unchanged */
534
+ /* |h0| <= 1.1*2^39 */
535
+
536
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
537
+ /* |h0| <= 2^25; from now on fits into int32 unchanged */
538
+ /* |h1| <= 1.01*2^24 */
539
+
540
+ h[0] = (int32_t)h0;
541
+ h[1] = (int32_t)h1;
542
+ h[2] = (int32_t)h2;
543
+ h[3] = (int32_t)h3;
544
+ h[4] = (int32_t)h4;
545
+ h[5] = (int32_t)h5;
546
+ h[6] = (int32_t)h6;
547
+ h[7] = (int32_t)h7;
548
+ h[8] = (int32_t)h8;
549
+ h[9] = (int32_t)h9;
550
+ }
551
+
552
+ /*
553
+ h = -f
554
+
555
+ Preconditions:
556
+ |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
557
+
558
+ Postconditions:
559
+ |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
560
+ */
561
+
562
+ void fe_neg(fe h,const fe f)
563
+ {
564
+ int32_t f0 = f[0];
565
+ int32_t f1 = f[1];
566
+ int32_t f2 = f[2];
567
+ int32_t f3 = f[3];
568
+ int32_t f4 = f[4];
569
+ int32_t f5 = f[5];
570
+ int32_t f6 = f[6];
571
+ int32_t f7 = f[7];
572
+ int32_t f8 = f[8];
573
+ int32_t f9 = f[9];
574
+ int32_t h0 = -f0;
575
+ int32_t h1 = -f1;
576
+ int32_t h2 = -f2;
577
+ int32_t h3 = -f3;
578
+ int32_t h4 = -f4;
579
+ int32_t h5 = -f5;
580
+ int32_t h6 = -f6;
581
+ int32_t h7 = -f7;
582
+ int32_t h8 = -f8;
583
+ int32_t h9 = -f9;
584
+ h[0] = h0;
585
+ h[1] = h1;
586
+ h[2] = h2;
587
+ h[3] = h3;
588
+ h[4] = h4;
589
+ h[5] = h5;
590
+ h[6] = h6;
591
+ h[7] = h7;
592
+ h[8] = h8;
593
+ h[9] = h9;
594
+ }
595
+
596
+ void fe_pow22523(fe out,const fe z)
597
+ {
598
+ fe t0;
599
+ fe t1;
600
+ fe t2;
601
+ int i;
602
+
603
+ #include "pow22523.h"
604
+
605
+ return;
606
+ }
607
+
608
+ /*
609
+ h = f * f
610
+ Can overlap h with f.
611
+
612
+ Preconditions:
613
+ |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
614
+
615
+ Postconditions:
616
+ |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
617
+ */
618
+
619
+ /*
620
+ See fe_mul.c for discussion of implementation strategy.
621
+ */
622
+
623
+ void fe_sq(fe h,const fe f)
624
+ {
625
+ int32_t f0 = f[0];
626
+ int32_t f1 = f[1];
627
+ int32_t f2 = f[2];
628
+ int32_t f3 = f[3];
629
+ int32_t f4 = f[4];
630
+ int32_t f5 = f[5];
631
+ int32_t f6 = f[6];
632
+ int32_t f7 = f[7];
633
+ int32_t f8 = f[8];
634
+ int32_t f9 = f[9];
635
+ int32_t f0_2 = 2 * f0;
636
+ int32_t f1_2 = 2 * f1;
637
+ int32_t f2_2 = 2 * f2;
638
+ int32_t f3_2 = 2 * f3;
639
+ int32_t f4_2 = 2 * f4;
640
+ int32_t f5_2 = 2 * f5;
641
+ int32_t f6_2 = 2 * f6;
642
+ int32_t f7_2 = 2 * f7;
643
+ int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
644
+ int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
645
+ int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
646
+ int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
647
+ int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
648
+ int64_t f0f0 = f0 * (int64_t) f0;
649
+ int64_t f0f1_2 = f0_2 * (int64_t) f1;
650
+ int64_t f0f2_2 = f0_2 * (int64_t) f2;
651
+ int64_t f0f3_2 = f0_2 * (int64_t) f3;
652
+ int64_t f0f4_2 = f0_2 * (int64_t) f4;
653
+ int64_t f0f5_2 = f0_2 * (int64_t) f5;
654
+ int64_t f0f6_2 = f0_2 * (int64_t) f6;
655
+ int64_t f0f7_2 = f0_2 * (int64_t) f7;
656
+ int64_t f0f8_2 = f0_2 * (int64_t) f8;
657
+ int64_t f0f9_2 = f0_2 * (int64_t) f9;
658
+ int64_t f1f1_2 = f1_2 * (int64_t) f1;
659
+ int64_t f1f2_2 = f1_2 * (int64_t) f2;
660
+ int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
661
+ int64_t f1f4_2 = f1_2 * (int64_t) f4;
662
+ int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
663
+ int64_t f1f6_2 = f1_2 * (int64_t) f6;
664
+ int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
665
+ int64_t f1f8_2 = f1_2 * (int64_t) f8;
666
+ int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
667
+ int64_t f2f2 = f2 * (int64_t) f2;
668
+ int64_t f2f3_2 = f2_2 * (int64_t) f3;
669
+ int64_t f2f4_2 = f2_2 * (int64_t) f4;
670
+ int64_t f2f5_2 = f2_2 * (int64_t) f5;
671
+ int64_t f2f6_2 = f2_2 * (int64_t) f6;
672
+ int64_t f2f7_2 = f2_2 * (int64_t) f7;
673
+ int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
674
+ int64_t f2f9_38 = f2 * (int64_t) f9_38;
675
+ int64_t f3f3_2 = f3_2 * (int64_t) f3;
676
+ int64_t f3f4_2 = f3_2 * (int64_t) f4;
677
+ int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
678
+ int64_t f3f6_2 = f3_2 * (int64_t) f6;
679
+ int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
680
+ int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
681
+ int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
682
+ int64_t f4f4 = f4 * (int64_t) f4;
683
+ int64_t f4f5_2 = f4_2 * (int64_t) f5;
684
+ int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
685
+ int64_t f4f7_38 = f4 * (int64_t) f7_38;
686
+ int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
687
+ int64_t f4f9_38 = f4 * (int64_t) f9_38;
688
+ int64_t f5f5_38 = f5 * (int64_t) f5_38;
689
+ int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
690
+ int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
691
+ int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
692
+ int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
693
+ int64_t f6f6_19 = f6 * (int64_t) f6_19;
694
+ int64_t f6f7_38 = f6 * (int64_t) f7_38;
695
+ int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
696
+ int64_t f6f9_38 = f6 * (int64_t) f9_38;
697
+ int64_t f7f7_38 = f7 * (int64_t) f7_38;
698
+ int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
699
+ int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
700
+ int64_t f8f8_19 = f8 * (int64_t) f8_19;
701
+ int64_t f8f9_38 = f8 * (int64_t) f9_38;
702
+ int64_t f9f9_38 = f9 * (int64_t) f9_38;
703
+ int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
704
+ int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
705
+ int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
706
+ int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
707
+ int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
708
+ int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
709
+ int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
710
+ int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
711
+ int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
712
+ int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
713
+ int64_t carry0;
714
+ int64_t carry1;
715
+ int64_t carry2;
716
+ int64_t carry3;
717
+ int64_t carry4;
718
+ int64_t carry5;
719
+ int64_t carry6;
720
+ int64_t carry7;
721
+ int64_t carry8;
722
+ int64_t carry9;
723
+
724
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
725
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
726
+
727
+ carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
728
+ carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
729
+
730
+ carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
731
+ carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
732
+
733
+ carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
734
+ carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
735
+
736
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
737
+ carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
738
+
739
+ carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
740
+
741
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
742
+
743
+ h[0] = (int32_t)h0;
744
+ h[1] = (int32_t)h1;
745
+ h[2] = (int32_t)h2;
746
+ h[3] = (int32_t)h3;
747
+ h[4] = (int32_t)h4;
748
+ h[5] = (int32_t)h5;
749
+ h[6] = (int32_t)h6;
750
+ h[7] = (int32_t)h7;
751
+ h[8] = (int32_t)h8;
752
+ h[9] = (int32_t)h9;
753
+ }
754
+
755
+ /*
756
+ h = 2 * f * f
757
+ Can overlap h with f.
758
+
759
+ Preconditions:
760
+ |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc.
761
+
762
+ Postconditions:
763
+ |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc.
764
+ */
765
+
766
+ /*
767
+ See fe_mul.c for discussion of implementation strategy.
768
+ */
769
+
770
+ void fe_sq2(fe h,const fe f)
771
+ {
772
+ int32_t f0 = f[0];
773
+ int32_t f1 = f[1];
774
+ int32_t f2 = f[2];
775
+ int32_t f3 = f[3];
776
+ int32_t f4 = f[4];
777
+ int32_t f5 = f[5];
778
+ int32_t f6 = f[6];
779
+ int32_t f7 = f[7];
780
+ int32_t f8 = f[8];
781
+ int32_t f9 = f[9];
782
+ int32_t f0_2 = 2 * f0;
783
+ int32_t f1_2 = 2 * f1;
784
+ int32_t f2_2 = 2 * f2;
785
+ int32_t f3_2 = 2 * f3;
786
+ int32_t f4_2 = 2 * f4;
787
+ int32_t f5_2 = 2 * f5;
788
+ int32_t f6_2 = 2 * f6;
789
+ int32_t f7_2 = 2 * f7;
790
+ int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */
791
+ int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */
792
+ int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */
793
+ int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */
794
+ int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */
795
+ int64_t f0f0 = f0 * (int64_t) f0;
796
+ int64_t f0f1_2 = f0_2 * (int64_t) f1;
797
+ int64_t f0f2_2 = f0_2 * (int64_t) f2;
798
+ int64_t f0f3_2 = f0_2 * (int64_t) f3;
799
+ int64_t f0f4_2 = f0_2 * (int64_t) f4;
800
+ int64_t f0f5_2 = f0_2 * (int64_t) f5;
801
+ int64_t f0f6_2 = f0_2 * (int64_t) f6;
802
+ int64_t f0f7_2 = f0_2 * (int64_t) f7;
803
+ int64_t f0f8_2 = f0_2 * (int64_t) f8;
804
+ int64_t f0f9_2 = f0_2 * (int64_t) f9;
805
+ int64_t f1f1_2 = f1_2 * (int64_t) f1;
806
+ int64_t f1f2_2 = f1_2 * (int64_t) f2;
807
+ int64_t f1f3_4 = f1_2 * (int64_t) f3_2;
808
+ int64_t f1f4_2 = f1_2 * (int64_t) f4;
809
+ int64_t f1f5_4 = f1_2 * (int64_t) f5_2;
810
+ int64_t f1f6_2 = f1_2 * (int64_t) f6;
811
+ int64_t f1f7_4 = f1_2 * (int64_t) f7_2;
812
+ int64_t f1f8_2 = f1_2 * (int64_t) f8;
813
+ int64_t f1f9_76 = f1_2 * (int64_t) f9_38;
814
+ int64_t f2f2 = f2 * (int64_t) f2;
815
+ int64_t f2f3_2 = f2_2 * (int64_t) f3;
816
+ int64_t f2f4_2 = f2_2 * (int64_t) f4;
817
+ int64_t f2f5_2 = f2_2 * (int64_t) f5;
818
+ int64_t f2f6_2 = f2_2 * (int64_t) f6;
819
+ int64_t f2f7_2 = f2_2 * (int64_t) f7;
820
+ int64_t f2f8_38 = f2_2 * (int64_t) f8_19;
821
+ int64_t f2f9_38 = f2 * (int64_t) f9_38;
822
+ int64_t f3f3_2 = f3_2 * (int64_t) f3;
823
+ int64_t f3f4_2 = f3_2 * (int64_t) f4;
824
+ int64_t f3f5_4 = f3_2 * (int64_t) f5_2;
825
+ int64_t f3f6_2 = f3_2 * (int64_t) f6;
826
+ int64_t f3f7_76 = f3_2 * (int64_t) f7_38;
827
+ int64_t f3f8_38 = f3_2 * (int64_t) f8_19;
828
+ int64_t f3f9_76 = f3_2 * (int64_t) f9_38;
829
+ int64_t f4f4 = f4 * (int64_t) f4;
830
+ int64_t f4f5_2 = f4_2 * (int64_t) f5;
831
+ int64_t f4f6_38 = f4_2 * (int64_t) f6_19;
832
+ int64_t f4f7_38 = f4 * (int64_t) f7_38;
833
+ int64_t f4f8_38 = f4_2 * (int64_t) f8_19;
834
+ int64_t f4f9_38 = f4 * (int64_t) f9_38;
835
+ int64_t f5f5_38 = f5 * (int64_t) f5_38;
836
+ int64_t f5f6_38 = f5_2 * (int64_t) f6_19;
837
+ int64_t f5f7_76 = f5_2 * (int64_t) f7_38;
838
+ int64_t f5f8_38 = f5_2 * (int64_t) f8_19;
839
+ int64_t f5f9_76 = f5_2 * (int64_t) f9_38;
840
+ int64_t f6f6_19 = f6 * (int64_t) f6_19;
841
+ int64_t f6f7_38 = f6 * (int64_t) f7_38;
842
+ int64_t f6f8_38 = f6_2 * (int64_t) f8_19;
843
+ int64_t f6f9_38 = f6 * (int64_t) f9_38;
844
+ int64_t f7f7_38 = f7 * (int64_t) f7_38;
845
+ int64_t f7f8_38 = f7_2 * (int64_t) f8_19;
846
+ int64_t f7f9_76 = f7_2 * (int64_t) f9_38;
847
+ int64_t f8f8_19 = f8 * (int64_t) f8_19;
848
+ int64_t f8f9_38 = f8 * (int64_t) f9_38;
849
+ int64_t f9f9_38 = f9 * (int64_t) f9_38;
850
+ int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38;
851
+ int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38;
852
+ int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19;
853
+ int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38;
854
+ int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38;
855
+ int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38;
856
+ int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19;
857
+ int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38;
858
+ int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38;
859
+ int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2;
860
+ int64_t carry0;
861
+ int64_t carry1;
862
+ int64_t carry2;
863
+ int64_t carry3;
864
+ int64_t carry4;
865
+ int64_t carry5;
866
+ int64_t carry6;
867
+ int64_t carry7;
868
+ int64_t carry8;
869
+ int64_t carry9;
870
+
871
+ h0 += h0;
872
+ h1 += h1;
873
+ h2 += h2;
874
+ h3 += h3;
875
+ h4 += h4;
876
+ h5 += h5;
877
+ h6 += h6;
878
+ h7 += h7;
879
+ h8 += h8;
880
+ h9 += h9;
881
+
882
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
883
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
884
+
885
+ carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25;
886
+ carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25;
887
+
888
+ carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26;
889
+ carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26;
890
+
891
+ carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25;
892
+ carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25;
893
+
894
+ carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26;
895
+ carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26;
896
+
897
+ carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25;
898
+
899
+ carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26;
900
+
901
+ h[0] = (int32_t)h0;
902
+ h[1] = (int32_t)h1;
903
+ h[2] = (int32_t)h2;
904
+ h[3] = (int32_t)h3;
905
+ h[4] = (int32_t)h4;
906
+ h[5] = (int32_t)h5;
907
+ h[6] = (int32_t)h6;
908
+ h[7] = (int32_t)h7;
909
+ h[8] = (int32_t)h8;
910
+ h[9] = (int32_t)h9;
911
+ }
912
+
913
+ /*
914
+ h = f - g
915
+ Can overlap h with f or g.
916
+
917
+ Preconditions:
918
+ |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
919
+ |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc.
920
+
921
+ Postconditions:
922
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
923
+ */
924
+
925
+ void fe_sub(fe h,const fe f,const fe g)
926
+ {
927
+ int32_t f0 = f[0];
928
+ int32_t f1 = f[1];
929
+ int32_t f2 = f[2];
930
+ int32_t f3 = f[3];
931
+ int32_t f4 = f[4];
932
+ int32_t f5 = f[5];
933
+ int32_t f6 = f[6];
934
+ int32_t f7 = f[7];
935
+ int32_t f8 = f[8];
936
+ int32_t f9 = f[9];
937
+ int32_t g0 = g[0];
938
+ int32_t g1 = g[1];
939
+ int32_t g2 = g[2];
940
+ int32_t g3 = g[3];
941
+ int32_t g4 = g[4];
942
+ int32_t g5 = g[5];
943
+ int32_t g6 = g[6];
944
+ int32_t g7 = g[7];
945
+ int32_t g8 = g[8];
946
+ int32_t g9 = g[9];
947
+ int32_t h0 = f0 - g0;
948
+ int32_t h1 = f1 - g1;
949
+ int32_t h2 = f2 - g2;
950
+ int32_t h3 = f3 - g3;
951
+ int32_t h4 = f4 - g4;
952
+ int32_t h5 = f5 - g5;
953
+ int32_t h6 = f6 - g6;
954
+ int32_t h7 = f7 - g7;
955
+ int32_t h8 = f8 - g8;
956
+ int32_t h9 = f9 - g9;
957
+ h[0] = h0;
958
+ h[1] = h1;
959
+ h[2] = h2;
960
+ h[3] = h3;
961
+ h[4] = h4;
962
+ h[5] = h5;
963
+ h[6] = h6;
964
+ h[7] = h7;
965
+ h[8] = h8;
966
+ h[9] = h9;
967
+ }
968
+
969
+ /*
970
+ Preconditions:
971
+ |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc.
972
+
973
+ Write p=2^255-19; q=floor(h/p).
974
+ Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))).
975
+
976
+ Proof:
977
+ Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4.
978
+ Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4.
979
+
980
+ Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9).
981
+ Then 0<y<1.
982
+
983
+ Write r=h-pq.
984
+ Have 0<=r<=p-1=2^255-20.
985
+ Thus 0<=r+19(2^-255)r<r+19(2^-255)2^255<=2^255-1.
986
+
987
+ Write x=r+19(2^-255)r+y.
988
+ Then 0<x<2^255 so floor(2^(-255)x) = 0 so floor(q+2^(-255)x) = q.
989
+
990
+ Have q+2^(-255)x = 2^(-255)(h + 19 2^(-25) h9 + 2^(-1))
991
+ so floor(2^(-255)(h + 19 2^(-25) h9 + 2^(-1))) = q.
992
+ */
993
+
994
+ void fe_tobytes(unsigned char *s,const fe h)
995
+ {
996
+ int32_t h0 = h[0];
997
+ int32_t h1 = h[1];
998
+ int32_t h2 = h[2];
999
+ int32_t h3 = h[3];
1000
+ int32_t h4 = h[4];
1001
+ int32_t h5 = h[5];
1002
+ int32_t h6 = h[6];
1003
+ int32_t h7 = h[7];
1004
+ int32_t h8 = h[8];
1005
+ int32_t h9 = h[9];
1006
+ int32_t q;
1007
+ int32_t carry0;
1008
+ int32_t carry1;
1009
+ int32_t carry2;
1010
+ int32_t carry3;
1011
+ int32_t carry4;
1012
+ int32_t carry5;
1013
+ int32_t carry6;
1014
+ int32_t carry7;
1015
+ int32_t carry8;
1016
+ int32_t carry9;
1017
+
1018
+ q = (19 * h9 + (((int32_t) 1) << 24)) >> 25;
1019
+ q = (h0 + q) >> 26;
1020
+ q = (h1 + q) >> 25;
1021
+ q = (h2 + q) >> 26;
1022
+ q = (h3 + q) >> 25;
1023
+ q = (h4 + q) >> 26;
1024
+ q = (h5 + q) >> 25;
1025
+ q = (h6 + q) >> 26;
1026
+ q = (h7 + q) >> 25;
1027
+ q = (h8 + q) >> 26;
1028
+ q = (h9 + q) >> 25;
1029
+
1030
+ /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
1031
+ h0 += 19 * q;
1032
+ /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
1033
+
1034
+ carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26;
1035
+ carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25;
1036
+ carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26;
1037
+ carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25;
1038
+ carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26;
1039
+ carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25;
1040
+ carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26;
1041
+ carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25;
1042
+ carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26;
1043
+ carry9 = h9 >> 25; h9 -= carry9 << 25;
1044
+ /* h10 = carry9 */
1045
+
1046
+ /*
1047
+ Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
1048
+ Have h0+...+2^230 h9 between 0 and 2^255-1;
1049
+ evidently 2^255 h10-2^255 q = 0.
1050
+ Goal: Output h0+...+2^230 h9.
1051
+ */
1052
+
1053
+ s[0] = h0 >> 0;
1054
+ s[1] = h0 >> 8;
1055
+ s[2] = h0 >> 16;
1056
+ s[3] = (h0 >> 24) | (h1 << 2);
1057
+ s[4] = h1 >> 6;
1058
+ s[5] = h1 >> 14;
1059
+ s[6] = (h1 >> 22) | (h2 << 3);
1060
+ s[7] = h2 >> 5;
1061
+ s[8] = h2 >> 13;
1062
+ s[9] = (h2 >> 21) | (h3 << 5);
1063
+ s[10] = h3 >> 3;
1064
+ s[11] = h3 >> 11;
1065
+ s[12] = (h3 >> 19) | (h4 << 6);
1066
+ s[13] = h4 >> 2;
1067
+ s[14] = h4 >> 10;
1068
+ s[15] = h4 >> 18;
1069
+ s[16] = h5 >> 0;
1070
+ s[17] = h5 >> 8;
1071
+ s[18] = h5 >> 16;
1072
+ s[19] = (h5 >> 24) | (h6 << 1);
1073
+ s[20] = h6 >> 7;
1074
+ s[21] = h6 >> 15;
1075
+ s[22] = (h6 >> 23) | (h7 << 3);
1076
+ s[23] = h7 >> 5;
1077
+ s[24] = h7 >> 13;
1078
+ s[25] = (h7 >> 21) | (h8 << 4);
1079
+ s[26] = h8 >> 4;
1080
+ s[27] = h8 >> 12;
1081
+ s[28] = (h8 >> 20) | (h9 << 6);
1082
+ s[29] = h9 >> 2;
1083
+ s[30] = h9 >> 10;
1084
+ s[31] = h9 >> 18;
1085
+ }