ed25519 1.2.4-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +5 -0
  4. data/.rubocop.yml +35 -0
  5. data/.travis.yml +26 -0
  6. data/CHANGES.md +70 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +12 -0
  9. data/LICENSE +22 -0
  10. data/README.md +170 -0
  11. data/Rakefile +27 -0
  12. data/appveyor.yml +21 -0
  13. data/ed25519.gemspec +32 -0
  14. data/ed25519.png +0 -0
  15. data/ext/ed25519_jruby/LICENSE.txt +123 -0
  16. data/ext/ed25519_jruby/README.md +77 -0
  17. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAEngine.java +491 -0
  18. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAKey.java +31 -0
  19. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAPrivateKey.java +338 -0
  20. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSAPublicKey.java +275 -0
  21. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/EdDSASecurityProvider.java +59 -0
  22. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/KeyFactory.java +75 -0
  23. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/KeyPairGenerator.java +97 -0
  24. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/Utils.java +103 -0
  25. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Constants.java +23 -0
  26. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Curve.java +100 -0
  27. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Encoding.java +54 -0
  28. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/Field.java +99 -0
  29. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/FieldElement.java +76 -0
  30. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/GroupElement.java +1034 -0
  31. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ScalarOps.java +34 -0
  32. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerFieldElement.java +131 -0
  33. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerLittleEndianEncoding.java +102 -0
  34. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/BigIntegerScalarOps.java +37 -0
  35. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/bigint/package.html +6 -0
  36. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519FieldElement.java +988 -0
  37. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519LittleEndianEncoding.java +256 -0
  38. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/math/ed25519/Ed25519ScalarOps.java +693 -0
  39. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAGenParameterSpec.java +32 -0
  40. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSANamedCurveSpec.java +35 -0
  41. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSANamedCurveTable.java +71 -0
  42. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAParameterSpec.java +97 -0
  43. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAPrivateKeySpec.java +133 -0
  44. data/ext/ed25519_jruby/net/i2p/crypto/eddsa/spec/EdDSAPublicKeySpec.java +61 -0
  45. data/ext/ed25519_jruby/org/cryptorb/Ed25519Provider.java +95 -0
  46. data/ext/ed25519_ref10/api.h +4 -0
  47. data/ext/ed25519_ref10/base.h +1344 -0
  48. data/ext/ed25519_ref10/base2.h +40 -0
  49. data/ext/ed25519_ref10/d.h +1 -0
  50. data/ext/ed25519_ref10/d2.h +1 -0
  51. data/ext/ed25519_ref10/ed25519_ref10.c +99 -0
  52. data/ext/ed25519_ref10/ed25519_ref10.h +33 -0
  53. data/ext/ed25519_ref10/extconf.rb +9 -0
  54. data/ext/ed25519_ref10/fe.c +1085 -0
  55. data/ext/ed25519_ref10/fe.h +56 -0
  56. data/ext/ed25519_ref10/ge.c +407 -0
  57. data/ext/ed25519_ref10/ge.h +95 -0
  58. data/ext/ed25519_ref10/ge_add.h +97 -0
  59. data/ext/ed25519_ref10/ge_madd.h +88 -0
  60. data/ext/ed25519_ref10/ge_msub.h +88 -0
  61. data/ext/ed25519_ref10/ge_p2_dbl.h +73 -0
  62. data/ext/ed25519_ref10/ge_sub.h +97 -0
  63. data/ext/ed25519_ref10/keypair.c +22 -0
  64. data/ext/ed25519_ref10/open.c +47 -0
  65. data/ext/ed25519_ref10/pow22523.h +160 -0
  66. data/ext/ed25519_ref10/pow225521.h +160 -0
  67. data/ext/ed25519_ref10/sc.h +17 -0
  68. data/ext/ed25519_ref10/sc_muladd.c +366 -0
  69. data/ext/ed25519_ref10/sc_reduce.c +272 -0
  70. data/ext/ed25519_ref10/sha512.c +304 -0
  71. data/ext/ed25519_ref10/sha512.h +8 -0
  72. data/ext/ed25519_ref10/sign.c +41 -0
  73. data/ext/ed25519_ref10/sqrtm1.h +1 -0
  74. data/ext/ed25519_ref10/verify.c +40 -0
  75. data/lib/ed25519.rb +72 -0
  76. data/lib/ed25519/signing_key.rb +60 -0
  77. data/lib/ed25519/verify_key.rb +44 -0
  78. data/lib/ed25519/version.rb +5 -0
  79. metadata +137 -0
@@ -0,0 +1,56 @@
1
+ #ifndef FE_H
2
+ #define FE_H
3
+
4
+ #include "ed25519_ref10.h"
5
+
6
+ typedef int32_t fe[10];
7
+
8
+ /*
9
+ fe means field element.
10
+ Here the field is \Z/(2^255-19).
11
+ An element t, entries t[0]...t[9], represents the integer
12
+ t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9].
13
+ Bounds on each t[i] vary depending on context.
14
+ */
15
+
16
+ #define fe_frombytes crypto_sign_ed25519_ref10_fe_frombytes
17
+ #define fe_tobytes crypto_sign_ed25519_ref10_fe_tobytes
18
+ #define fe_copy crypto_sign_ed25519_ref10_fe_copy
19
+ #define fe_isnonzero crypto_sign_ed25519_ref10_fe_isnonzero
20
+ #define fe_isnegative crypto_sign_ed25519_ref10_fe_isnegative
21
+ #define fe_0 crypto_sign_ed25519_ref10_fe_0
22
+ #define fe_1 crypto_sign_ed25519_ref10_fe_1
23
+ #define fe_cswap crypto_sign_ed25519_ref10_fe_cswap
24
+ #define fe_cmov crypto_sign_ed25519_ref10_fe_cmov
25
+ #define fe_add crypto_sign_ed25519_ref10_fe_add
26
+ #define fe_sub crypto_sign_ed25519_ref10_fe_sub
27
+ #define fe_neg crypto_sign_ed25519_ref10_fe_neg
28
+ #define fe_mul crypto_sign_ed25519_ref10_fe_mul
29
+ #define fe_sq crypto_sign_ed25519_ref10_fe_sq
30
+ #define fe_sq2 crypto_sign_ed25519_ref10_fe_sq2
31
+ #define fe_mul121666 crypto_sign_ed25519_ref10_fe_mul121666
32
+ #define fe_invert crypto_sign_ed25519_ref10_fe_invert
33
+ #define fe_pow22523 crypto_sign_ed25519_ref10_fe_pow22523
34
+
35
+ extern void fe_frombytes(fe,const unsigned char *);
36
+ extern void fe_tobytes(unsigned char *,const fe);
37
+
38
+ extern void fe_copy(fe,const fe);
39
+ extern int fe_isnonzero(const fe);
40
+ extern int fe_isnegative(const fe);
41
+ extern void fe_0(fe);
42
+ extern void fe_1(fe);
43
+ extern void fe_cswap(fe,fe,unsigned int);
44
+ extern void fe_cmov(fe,const fe,unsigned int);
45
+
46
+ extern void fe_add(fe,const fe,const fe);
47
+ extern void fe_sub(fe,const fe,const fe);
48
+ extern void fe_neg(fe,const fe);
49
+ extern void fe_mul(fe,const fe,const fe);
50
+ extern void fe_sq(fe,const fe);
51
+ extern void fe_sq2(fe,const fe);
52
+ extern void fe_mul121666(fe,const fe);
53
+ extern void fe_invert(fe,const fe);
54
+ extern void fe_pow22523(fe,const fe);
55
+
56
+ #endif
@@ -0,0 +1,407 @@
1
+ #include "ge.h"
2
+
3
+ /*
4
+ r = p + q
5
+ */
6
+
7
+ void ge_add(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q)
8
+ {
9
+ fe t0;
10
+ #include "ge_add.h"
11
+ }
12
+
13
+ static void slide(signed char *r,const unsigned char *a)
14
+ {
15
+ int i;
16
+ int b;
17
+ int k;
18
+
19
+ for (i = 0;i < 256;++i)
20
+ r[i] = 1 & (a[i >> 3] >> (i & 7));
21
+
22
+ for (i = 0;i < 256;++i)
23
+ if (r[i]) {
24
+ for (b = 1;b <= 6 && i + b < 256;++b) {
25
+ if (r[i + b]) {
26
+ if (r[i] + (r[i + b] << b) <= 15) {
27
+ r[i] += r[i + b] << b; r[i + b] = 0;
28
+ } else if (r[i] - (r[i + b] << b) >= -15) {
29
+ r[i] -= r[i + b] << b;
30
+ for (k = i + b;k < 256;++k) {
31
+ if (!r[k]) {
32
+ r[k] = 1;
33
+ break;
34
+ }
35
+ r[k] = 0;
36
+ }
37
+ } else
38
+ break;
39
+ }
40
+ }
41
+ }
42
+
43
+ }
44
+
45
+ static ge_precomp Bi[8] = {
46
+ #include "base2.h"
47
+ } ;
48
+
49
+ /*
50
+ r = a * A + b * B
51
+ where a = a[0]+256*a[1]+...+256^31 a[31].
52
+ and b = b[0]+256*b[1]+...+256^31 b[31].
53
+ B is the Ed25519 base point (x,4/5) with x positive.
54
+ */
55
+
56
+ void ge_double_scalarmult_vartime(ge_p2 *r,const unsigned char *a,const ge_p3 *A,const unsigned char *b)
57
+ {
58
+ signed char aslide[256];
59
+ signed char bslide[256];
60
+ ge_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */
61
+ ge_p1p1 t;
62
+ ge_p3 u;
63
+ ge_p3 A2;
64
+ int i;
65
+
66
+ slide(aslide,a);
67
+ slide(bslide,b);
68
+
69
+ ge_p3_to_cached(&Ai[0],A);
70
+ ge_p3_dbl(&t,A); ge_p1p1_to_p3(&A2,&t);
71
+ ge_add(&t,&A2,&Ai[0]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[1],&u);
72
+ ge_add(&t,&A2,&Ai[1]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[2],&u);
73
+ ge_add(&t,&A2,&Ai[2]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[3],&u);
74
+ ge_add(&t,&A2,&Ai[3]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[4],&u);
75
+ ge_add(&t,&A2,&Ai[4]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[5],&u);
76
+ ge_add(&t,&A2,&Ai[5]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[6],&u);
77
+ ge_add(&t,&A2,&Ai[6]); ge_p1p1_to_p3(&u,&t); ge_p3_to_cached(&Ai[7],&u);
78
+
79
+ ge_p2_0(r);
80
+
81
+ for (i = 255;i >= 0;--i) {
82
+ if (aslide[i] || bslide[i]) break;
83
+ }
84
+
85
+ for (;i >= 0;--i) {
86
+ ge_p2_dbl(&t,r);
87
+
88
+ if (aslide[i] > 0) {
89
+ ge_p1p1_to_p3(&u,&t);
90
+ ge_add(&t,&u,&Ai[aslide[i]/2]);
91
+ } else if (aslide[i] < 0) {
92
+ ge_p1p1_to_p3(&u,&t);
93
+ ge_sub(&t,&u,&Ai[(-aslide[i])/2]);
94
+ }
95
+
96
+ if (bslide[i] > 0) {
97
+ ge_p1p1_to_p3(&u,&t);
98
+ ge_madd(&t,&u,&Bi[bslide[i]/2]);
99
+ } else if (bslide[i] < 0) {
100
+ ge_p1p1_to_p3(&u,&t);
101
+ ge_msub(&t,&u,&Bi[(-bslide[i])/2]);
102
+ }
103
+
104
+ ge_p1p1_to_p2(r,&t);
105
+ }
106
+ }
107
+
108
+ static const fe d = {
109
+ #include "d.h"
110
+ } ;
111
+
112
+ static const fe sqrtm1 = {
113
+ #include "sqrtm1.h"
114
+ } ;
115
+
116
+ int ge_frombytes_negate_vartime(ge_p3 *h,const unsigned char *s)
117
+ {
118
+ fe u;
119
+ fe v;
120
+ fe v3;
121
+ fe vxx;
122
+ fe check;
123
+
124
+ fe_frombytes(h->Y,s);
125
+ fe_1(h->Z);
126
+ fe_sq(u,h->Y);
127
+ fe_mul(v,u,d);
128
+ fe_sub(u,u,h->Z); /* u = y^2-1 */
129
+ fe_add(v,v,h->Z); /* v = dy^2+1 */
130
+
131
+ fe_sq(v3,v);
132
+ fe_mul(v3,v3,v); /* v3 = v^3 */
133
+ fe_sq(h->X,v3);
134
+ fe_mul(h->X,h->X,v);
135
+ fe_mul(h->X,h->X,u); /* x = uv^7 */
136
+
137
+ fe_pow22523(h->X,h->X); /* x = (uv^7)^((q-5)/8) */
138
+ fe_mul(h->X,h->X,v3);
139
+ fe_mul(h->X,h->X,u); /* x = uv^3(uv^7)^((q-5)/8) */
140
+
141
+ fe_sq(vxx,h->X);
142
+ fe_mul(vxx,vxx,v);
143
+ fe_sub(check,vxx,u); /* vx^2-u */
144
+ if (fe_isnonzero(check)) {
145
+ fe_add(check,vxx,u); /* vx^2+u */
146
+ if (fe_isnonzero(check)) return -1;
147
+ fe_mul(h->X,h->X,sqrtm1);
148
+ }
149
+
150
+ if (fe_isnegative(h->X) == (s[31] >> 7))
151
+ fe_neg(h->X,h->X);
152
+
153
+ fe_mul(h->T,h->X,h->Y);
154
+ return 0;
155
+ }
156
+
157
+ /*
158
+ r = p + q
159
+ */
160
+
161
+ void ge_madd(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q)
162
+ {
163
+ fe t0;
164
+ #include "ge_madd.h"
165
+ }
166
+
167
+ /*
168
+ r = p - q
169
+ */
170
+
171
+ void ge_msub(ge_p1p1 *r,const ge_p3 *p,const ge_precomp *q)
172
+ {
173
+ fe t0;
174
+ #include "ge_msub.h"
175
+ }
176
+
177
+ /*
178
+ r = p
179
+ */
180
+
181
+ extern void ge_p1p1_to_p2(ge_p2 *r,const ge_p1p1 *p)
182
+ {
183
+ fe_mul(r->X,p->X,p->T);
184
+ fe_mul(r->Y,p->Y,p->Z);
185
+ fe_mul(r->Z,p->Z,p->T);
186
+ }
187
+
188
+ /*
189
+ r = p
190
+ */
191
+
192
+ extern void ge_p1p1_to_p3(ge_p3 *r,const ge_p1p1 *p)
193
+ {
194
+ fe_mul(r->X,p->X,p->T);
195
+ fe_mul(r->Y,p->Y,p->Z);
196
+ fe_mul(r->Z,p->Z,p->T);
197
+ fe_mul(r->T,p->X,p->Y);
198
+ }
199
+
200
+ void ge_p2_0(ge_p2 *h)
201
+ {
202
+ fe_0(h->X);
203
+ fe_1(h->Y);
204
+ fe_1(h->Z);
205
+ }
206
+
207
+ /*
208
+ r = 2 * p
209
+ */
210
+
211
+ void ge_p2_dbl(ge_p1p1 *r,const ge_p2 *p)
212
+ {
213
+ fe t0;
214
+ #include "ge_p2_dbl.h"
215
+ }
216
+
217
+ void ge_p3_0(ge_p3 *h)
218
+ {
219
+ fe_0(h->X);
220
+ fe_1(h->Y);
221
+ fe_1(h->Z);
222
+ fe_0(h->T);
223
+ }
224
+
225
+ /*
226
+ r = 2 * p
227
+ */
228
+
229
+ void ge_p3_dbl(ge_p1p1 *r,const ge_p3 *p)
230
+ {
231
+ ge_p2 q;
232
+ ge_p3_to_p2(&q,p);
233
+ ge_p2_dbl(r,&q);
234
+ }
235
+
236
+ /*
237
+ r = p
238
+ */
239
+
240
+ static const fe d2 = {
241
+ #include "d2.h"
242
+ } ;
243
+
244
+ extern void ge_p3_to_cached(ge_cached *r,const ge_p3 *p)
245
+ {
246
+ fe_add(r->YplusX,p->Y,p->X);
247
+ fe_sub(r->YminusX,p->Y,p->X);
248
+ fe_copy(r->Z,p->Z);
249
+ fe_mul(r->T2d,p->T,d2);
250
+ }
251
+
252
+ /*
253
+ r = p
254
+ */
255
+
256
+ extern void ge_p3_to_p2(ge_p2 *r,const ge_p3 *p)
257
+ {
258
+ fe_copy(r->X,p->X);
259
+ fe_copy(r->Y,p->Y);
260
+ fe_copy(r->Z,p->Z);
261
+ }
262
+
263
+ void ge_p3_tobytes(unsigned char *s,const ge_p3 *h)
264
+ {
265
+ fe recip;
266
+ fe x;
267
+ fe y;
268
+
269
+ fe_invert(recip,h->Z);
270
+ fe_mul(x,h->X,recip);
271
+ fe_mul(y,h->Y,recip);
272
+ fe_tobytes(s,y);
273
+ s[31] ^= fe_isnegative(x) << 7;
274
+ }
275
+
276
+ void ge_precomp_0(ge_precomp *h)
277
+ {
278
+ fe_1(h->yplusx);
279
+ fe_1(h->yminusx);
280
+ fe_0(h->xy2d);
281
+ }
282
+
283
+ static uint8_t equal(int8_t b,int8_t c)
284
+ {
285
+ uint8_t ub = b;
286
+ uint8_t uc = c;
287
+ uint8_t x = ub ^ uc; /* 0: yes; 1..255: no */
288
+ uint32_t y = x; /* 0: yes; 1..255: no */
289
+ y -= 1; /* 4294967295: yes; 0..254: no */
290
+ y >>= 31; /* 1: yes; 0: no */
291
+ return y;
292
+ }
293
+
294
+ static uint8_t negative(int8_t b)
295
+ {
296
+ unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
297
+ x >>= 63; /* 1: yes; 0: no */
298
+ return x;
299
+ }
300
+
301
+ static void cmov(ge_precomp *t,ge_precomp *u,int8_t b)
302
+ {
303
+ fe_cmov(t->yplusx,u->yplusx,b);
304
+ fe_cmov(t->yminusx,u->yminusx,b);
305
+ fe_cmov(t->xy2d,u->xy2d,b);
306
+ }
307
+
308
+ /* base[i][j] = (j+1)*256^i*B */
309
+ static ge_precomp base[32][8] = {
310
+ #include "base.h"
311
+ } ;
312
+
313
+ static void select(ge_precomp *t,int pos,int8_t b)
314
+ {
315
+ ge_precomp minust;
316
+ uint8_t bnegative = negative(b);
317
+ uint8_t babs = b - (((-bnegative) & b) << 1);
318
+
319
+ ge_precomp_0(t);
320
+ cmov(t,&base[pos][0],equal(babs,1));
321
+ cmov(t,&base[pos][1],equal(babs,2));
322
+ cmov(t,&base[pos][2],equal(babs,3));
323
+ cmov(t,&base[pos][3],equal(babs,4));
324
+ cmov(t,&base[pos][4],equal(babs,5));
325
+ cmov(t,&base[pos][5],equal(babs,6));
326
+ cmov(t,&base[pos][6],equal(babs,7));
327
+ cmov(t,&base[pos][7],equal(babs,8));
328
+ fe_copy(minust.yplusx,t->yminusx);
329
+ fe_copy(minust.yminusx,t->yplusx);
330
+ fe_neg(minust.xy2d,t->xy2d);
331
+ cmov(t,&minust,bnegative);
332
+ }
333
+
334
+ /*
335
+ h = a * B
336
+ where a = a[0]+256*a[1]+...+256^31 a[31]
337
+ B is the Ed25519 base point (x,4/5) with x positive.
338
+
339
+ Preconditions:
340
+ a[31] <= 127
341
+ */
342
+
343
+ void ge_scalarmult_base(ge_p3 *h,const uint8_t *a)
344
+ {
345
+ int8_t e[64];
346
+ int8_t carry;
347
+ ge_p1p1 r;
348
+ ge_p2 s;
349
+ ge_precomp t;
350
+ int i;
351
+
352
+ for (i = 0;i < 32;++i) {
353
+ e[2 * i + 0] = (a[i] >> 0) & 15;
354
+ e[2 * i + 1] = (a[i] >> 4) & 15;
355
+ }
356
+ /* each e[i] is between 0 and 15 */
357
+ /* e[63] is between 0 and 7 */
358
+
359
+ carry = 0;
360
+ for (i = 0;i < 63;++i) {
361
+ e[i] += carry;
362
+ carry = e[i] + 8;
363
+ carry >>= 4;
364
+ e[i] -= carry << 4;
365
+ }
366
+ e[63] += carry;
367
+ /* each e[i] is between -8 and 8 */
368
+
369
+ ge_p3_0(h);
370
+ for (i = 1;i < 64;i += 2) {
371
+ select(&t,i / 2,e[i]);
372
+ ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r);
373
+ }
374
+
375
+ ge_p3_dbl(&r,h); ge_p1p1_to_p2(&s,&r);
376
+ ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);
377
+ ge_p2_dbl(&r,&s); ge_p1p1_to_p2(&s,&r);
378
+ ge_p2_dbl(&r,&s); ge_p1p1_to_p3(h,&r);
379
+
380
+ for (i = 0;i < 64;i += 2) {
381
+ select(&t,i / 2,e[i]);
382
+ ge_madd(&r,h,&t); ge_p1p1_to_p3(h,&r);
383
+ }
384
+ }
385
+
386
+ /*
387
+ r = p - q
388
+ */
389
+
390
+ void ge_sub(ge_p1p1 *r,const ge_p3 *p,const ge_cached *q)
391
+ {
392
+ fe t0;
393
+ #include "ge_sub.h"
394
+ }
395
+
396
+ void ge_tobytes(unsigned char *s,const ge_p2 *h)
397
+ {
398
+ fe recip;
399
+ fe x;
400
+ fe y;
401
+
402
+ fe_invert(recip,h->Z);
403
+ fe_mul(x,h->X,recip);
404
+ fe_mul(y,h->Y,recip);
405
+ fe_tobytes(s,y);
406
+ s[31] ^= fe_isnegative(x) << 7;
407
+ }