red25519 1.1.0-jruby

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,326 @@
1
+ #define WINDOWSIZE 1 /* Should be 1,2, or 4 */
2
+ #define WINDOWMASK ((1<<WINDOWSIZE)-1)
3
+
4
+ #include "fe25519.h"
5
+
6
+ static crypto_uint32 equal(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
7
+ {
8
+ crypto_uint32 x = a ^ b; /* 0: yes; 1..65535: no */
9
+ x -= 1; /* 4294967295: yes; 0..65534: no */
10
+ x >>= 31; /* 1: yes; 0: no */
11
+ return x;
12
+ }
13
+
14
+ static crypto_uint32 ge(crypto_uint32 a,crypto_uint32 b) /* 16-bit inputs */
15
+ {
16
+ unsigned int x = a;
17
+ x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */
18
+ x >>= 31; /* 0: yes; 1: no */
19
+ x ^= 1; /* 1: yes; 0: no */
20
+ return x;
21
+ }
22
+
23
+ static crypto_uint32 times19(crypto_uint32 a)
24
+ {
25
+ return (a << 4) + (a << 1) + a;
26
+ }
27
+
28
+ static crypto_uint32 times38(crypto_uint32 a)
29
+ {
30
+ return (a << 5) + (a << 2) + (a << 1);
31
+ }
32
+
33
+ static void reduce_add_sub(fe25519 *r)
34
+ {
35
+ crypto_uint32 t;
36
+ int i,rep;
37
+
38
+ for(rep=0;rep<4;rep++)
39
+ {
40
+ t = r->v[31] >> 7;
41
+ r->v[31] &= 127;
42
+ t = times19(t);
43
+ r->v[0] += t;
44
+ for(i=0;i<31;i++)
45
+ {
46
+ t = r->v[i] >> 8;
47
+ r->v[i+1] += t;
48
+ r->v[i] &= 255;
49
+ }
50
+ }
51
+ }
52
+
53
+ static void reduce_mul(fe25519 *r)
54
+ {
55
+ crypto_uint32 t;
56
+ int i,rep;
57
+
58
+ for(rep=0;rep<2;rep++)
59
+ {
60
+ t = r->v[31] >> 7;
61
+ r->v[31] &= 127;
62
+ t = times19(t);
63
+ r->v[0] += t;
64
+ for(i=0;i<31;i++)
65
+ {
66
+ t = r->v[i] >> 8;
67
+ r->v[i+1] += t;
68
+ r->v[i] &= 255;
69
+ }
70
+ }
71
+ }
72
+
73
+ /* reduction modulo 2^255-19 */
74
+ void fe25519_freeze(fe25519 *r)
75
+ {
76
+ int i;
77
+ crypto_uint32 m = equal(r->v[31],127);
78
+ for(i=30;i>0;i--)
79
+ m &= equal(r->v[i],255);
80
+ m &= ge(r->v[0],237);
81
+
82
+ m = -m;
83
+
84
+ r->v[31] -= m&127;
85
+ for(i=30;i>0;i--)
86
+ r->v[i] -= m&255;
87
+ r->v[0] -= m&237;
88
+ }
89
+
90
+ void fe25519_unpack(fe25519 *r, const unsigned char x[32])
91
+ {
92
+ int i;
93
+ for(i=0;i<32;i++) r->v[i] = x[i];
94
+ r->v[31] &= 127;
95
+ }
96
+
97
+ /* Assumes input x being reduced below 2^255 */
98
+ void fe25519_pack(unsigned char r[32], const fe25519 *x)
99
+ {
100
+ int i;
101
+ fe25519 y = *x;
102
+ fe25519_freeze(&y);
103
+ for(i=0;i<32;i++)
104
+ r[i] = y.v[i];
105
+ }
106
+
107
+ int fe25519_iszero(const fe25519 *x)
108
+ {
109
+ int i, r;
110
+ fe25519 t = *x;
111
+ fe25519_freeze(&t);
112
+ r = equal(t.v[0],0);
113
+ for(i=1;i<32;i++)
114
+ r &= equal(t.v[i],0);
115
+ return r;
116
+ }
117
+
118
+ int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
119
+ {
120
+ int i;
121
+ fe25519 t1 = *x;
122
+ fe25519 t2 = *y;
123
+ fe25519_freeze(&t1);
124
+ fe25519_freeze(&t2);
125
+ for(i=0;i<32;i++)
126
+ if(t1.v[i] != t2.v[i]) return 0;
127
+ return 1;
128
+ }
129
+
130
+ void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
131
+ {
132
+ int i;
133
+ crypto_uint32 mask = b;
134
+ mask = -mask;
135
+ for(i=0;i<32;i++) r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
136
+ }
137
+
138
+ unsigned char fe25519_getparity(const fe25519 *x)
139
+ {
140
+ fe25519 t = *x;
141
+ fe25519_freeze(&t);
142
+ return t.v[0] & 1;
143
+ }
144
+
145
+ void fe25519_setone(fe25519 *r)
146
+ {
147
+ int i;
148
+ r->v[0] = 1;
149
+ for(i=1;i<32;i++) r->v[i]=0;
150
+ }
151
+
152
+ void fe25519_setzero(fe25519 *r)
153
+ {
154
+ int i;
155
+ for(i=0;i<32;i++) r->v[i]=0;
156
+ }
157
+
158
+ void fe25519_neg(fe25519 *r, const fe25519 *x)
159
+ {
160
+ fe25519 t;
161
+ int i;
162
+ for(i=0;i<32;i++) t.v[i]=x->v[i];
163
+ fe25519_setzero(r);
164
+ fe25519_sub(r, r, &t);
165
+ }
166
+
167
+ void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
168
+ {
169
+ int i;
170
+ for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i];
171
+ reduce_add_sub(r);
172
+ }
173
+
174
+ void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
175
+ {
176
+ int i;
177
+ crypto_uint32 t[32];
178
+ t[0] = x->v[0] + 0x1da;
179
+ t[31] = x->v[31] + 0xfe;
180
+ for(i=1;i<31;i++) t[i] = x->v[i] + 0x1fe;
181
+ for(i=0;i<32;i++) r->v[i] = t[i] - y->v[i];
182
+ reduce_add_sub(r);
183
+ }
184
+
185
+ void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
186
+ {
187
+ int i,j;
188
+ crypto_uint32 t[63];
189
+ for(i=0;i<63;i++)t[i] = 0;
190
+
191
+ for(i=0;i<32;i++)
192
+ for(j=0;j<32;j++)
193
+ t[i+j] += x->v[i] * y->v[j];
194
+
195
+ for(i=32;i<63;i++)
196
+ r->v[i-32] = t[i-32] + times38(t[i]);
197
+ r->v[31] = t[31]; /* result now in r[0]...r[31] */
198
+
199
+ reduce_mul(r);
200
+ }
201
+
202
+ void fe25519_square(fe25519 *r, const fe25519 *x)
203
+ {
204
+ fe25519_mul(r, x, x);
205
+ }
206
+
207
+ void fe25519_invert(fe25519 *r, const fe25519 *x)
208
+ {
209
+ fe25519 z2;
210
+ fe25519 z9;
211
+ fe25519 z11;
212
+ fe25519 z2_5_0;
213
+ fe25519 z2_10_0;
214
+ fe25519 z2_20_0;
215
+ fe25519 z2_50_0;
216
+ fe25519 z2_100_0;
217
+ fe25519 t0;
218
+ fe25519 t1;
219
+ int i;
220
+
221
+ /* 2 */ fe25519_square(&z2,x);
222
+ /* 4 */ fe25519_square(&t1,&z2);
223
+ /* 8 */ fe25519_square(&t0,&t1);
224
+ /* 9 */ fe25519_mul(&z9,&t0,x);
225
+ /* 11 */ fe25519_mul(&z11,&z9,&z2);
226
+ /* 22 */ fe25519_square(&t0,&z11);
227
+ /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t0,&z9);
228
+
229
+ /* 2^6 - 2^1 */ fe25519_square(&t0,&z2_5_0);
230
+ /* 2^7 - 2^2 */ fe25519_square(&t1,&t0);
231
+ /* 2^8 - 2^3 */ fe25519_square(&t0,&t1);
232
+ /* 2^9 - 2^4 */ fe25519_square(&t1,&t0);
233
+ /* 2^10 - 2^5 */ fe25519_square(&t0,&t1);
234
+ /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t0,&z2_5_0);
235
+
236
+ /* 2^11 - 2^1 */ fe25519_square(&t0,&z2_10_0);
237
+ /* 2^12 - 2^2 */ fe25519_square(&t1,&t0);
238
+ /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
239
+ /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t1,&z2_10_0);
240
+
241
+ /* 2^21 - 2^1 */ fe25519_square(&t0,&z2_20_0);
242
+ /* 2^22 - 2^2 */ fe25519_square(&t1,&t0);
243
+ /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
244
+ /* 2^40 - 2^0 */ fe25519_mul(&t0,&t1,&z2_20_0);
245
+
246
+ /* 2^41 - 2^1 */ fe25519_square(&t1,&t0);
247
+ /* 2^42 - 2^2 */ fe25519_square(&t0,&t1);
248
+ /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
249
+ /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0);
250
+
251
+ /* 2^51 - 2^1 */ fe25519_square(&t0,&z2_50_0);
252
+ /* 2^52 - 2^2 */ fe25519_square(&t1,&t0);
253
+ /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
254
+ /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t1,&z2_50_0);
255
+
256
+ /* 2^101 - 2^1 */ fe25519_square(&t1,&z2_100_0);
257
+ /* 2^102 - 2^2 */ fe25519_square(&t0,&t1);
258
+ /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); }
259
+ /* 2^200 - 2^0 */ fe25519_mul(&t1,&t0,&z2_100_0);
260
+
261
+ /* 2^201 - 2^1 */ fe25519_square(&t0,&t1);
262
+ /* 2^202 - 2^2 */ fe25519_square(&t1,&t0);
263
+ /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); }
264
+ /* 2^250 - 2^0 */ fe25519_mul(&t0,&t1,&z2_50_0);
265
+
266
+ /* 2^251 - 2^1 */ fe25519_square(&t1,&t0);
267
+ /* 2^252 - 2^2 */ fe25519_square(&t0,&t1);
268
+ /* 2^253 - 2^3 */ fe25519_square(&t1,&t0);
269
+ /* 2^254 - 2^4 */ fe25519_square(&t0,&t1);
270
+ /* 2^255 - 2^5 */ fe25519_square(&t1,&t0);
271
+ /* 2^255 - 21 */ fe25519_mul(r,&t1,&z11);
272
+ }
273
+
274
+ void fe25519_pow2523(fe25519 *r, const fe25519 *x)
275
+ {
276
+ fe25519 z2;
277
+ fe25519 z9;
278
+ fe25519 z11;
279
+ fe25519 z2_5_0;
280
+ fe25519 z2_10_0;
281
+ fe25519 z2_20_0;
282
+ fe25519 z2_50_0;
283
+ fe25519 z2_100_0;
284
+ fe25519 t;
285
+ int i;
286
+
287
+ /* 2 */ fe25519_square(&z2,x);
288
+ /* 4 */ fe25519_square(&t,&z2);
289
+ /* 8 */ fe25519_square(&t,&t);
290
+ /* 9 */ fe25519_mul(&z9,&t,x);
291
+ /* 11 */ fe25519_mul(&z11,&z9,&z2);
292
+ /* 22 */ fe25519_square(&t,&z11);
293
+ /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9);
294
+
295
+ /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0);
296
+ /* 2^10 - 2^5 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); }
297
+ /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0);
298
+
299
+ /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0);
300
+ /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
301
+ /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0);
302
+
303
+ /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0);
304
+ /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); }
305
+ /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0);
306
+
307
+ /* 2^41 - 2^1 */ fe25519_square(&t,&t);
308
+ /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
309
+ /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0);
310
+
311
+ /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0);
312
+ /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
313
+ /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0);
314
+
315
+ /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0);
316
+ /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); }
317
+ /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0);
318
+
319
+ /* 2^201 - 2^1 */ fe25519_square(&t,&t);
320
+ /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
321
+ /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0);
322
+
323
+ /* 2^251 - 2^1 */ fe25519_square(&t,&t);
324
+ /* 2^252 - 2^2 */ fe25519_square(&t,&t);
325
+ /* 2^252 - 3 */ fe25519_mul(r,&t,x);
326
+ }
@@ -0,0 +1,63 @@
1
+ #ifndef FE25519_H
2
+ #define FE25519_H
3
+
4
+ #include "crypto_int32.h"
5
+ #include "crypto_uint32.h"
6
+
7
+ #define fe25519 crypto_sign_ed25519_ref_fe25519
8
+ #define fe25519_freeze crypto_sign_ed25519_ref_fe25519_freeze
9
+ #define fe25519_unpack crypto_sign_ed25519_ref_fe25519_unpack
10
+ #define fe25519_pack crypto_sign_ed25519_ref_fe25519_pack
11
+ #define fe25519_iszero crypto_sign_ed25519_ref_fe25519_iszero
12
+ #define fe25519_iseq_vartime crypto_sign_ed25519_ref_fe25519_iseq_vartime
13
+ #define fe25519_cmov crypto_sign_ed25519_ref_fe25519_cmov
14
+ #define fe25519_setone crypto_sign_ed25519_ref_fe25519_setone
15
+ #define fe25519_setzero crypto_sign_ed25519_ref_fe25519_setzero
16
+ #define fe25519_neg crypto_sign_ed25519_ref_fe25519_neg
17
+ #define fe25519_getparity crypto_sign_ed25519_ref_fe25519_getparity
18
+ #define fe25519_add crypto_sign_ed25519_ref_fe25519_add
19
+ #define fe25519_sub crypto_sign_ed25519_ref_fe25519_sub
20
+ #define fe25519_mul crypto_sign_ed25519_ref_fe25519_mul
21
+ #define fe25519_square crypto_sign_ed25519_ref_fe25519_square
22
+ #define fe25519_invert crypto_sign_ed25519_ref_fe25519_invert
23
+ #define fe25519_pow2523 crypto_sign_ed25519_ref_fe25519_pow2523
24
+
25
+ typedef struct
26
+ {
27
+ crypto_uint32 v[32];
28
+ }
29
+ fe25519;
30
+
31
+ void fe25519_freeze(fe25519 *r);
32
+
33
+ void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
34
+
35
+ void fe25519_pack(unsigned char r[32], const fe25519 *x);
36
+
37
+ int fe25519_iszero(const fe25519 *x);
38
+
39
+ int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y);
40
+
41
+ void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b);
42
+
43
+ void fe25519_setone(fe25519 *r);
44
+
45
+ void fe25519_setzero(fe25519 *r);
46
+
47
+ void fe25519_neg(fe25519 *r, const fe25519 *x);
48
+
49
+ unsigned char fe25519_getparity(const fe25519 *x);
50
+
51
+ void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y);
52
+
53
+ void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y);
54
+
55
+ void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y);
56
+
57
+ void fe25519_square(fe25519 *r, const fe25519 *x);
58
+
59
+ void fe25519_invert(fe25519 *r, const fe25519 *x);
60
+
61
+ void fe25519_pow2523(fe25519 *r, const fe25519 *x);
62
+
63
+ #endif
@@ -0,0 +1,311 @@
1
+ #include "fe25519.h"
2
+ #include "sc25519.h"
3
+ #include "ge25519.h"
4
+
5
+ /*
6
+ * Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2
7
+ * with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555
8
+ * Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960);
9
+ */
10
+
11
+ /* d */
12
+ static const fe25519 ge25519_ecd = {{0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00,
13
+ 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}};
14
+ /* 2*d */
15
+ static const fe25519 ge25519_ec2d = {{0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB, 0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00,
16
+ 0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19, 0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24}};
17
+ /* sqrt(-1) */
18
+ static const fe25519 ge25519_sqrtm1 = {{0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4, 0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F,
19
+ 0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B, 0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B}};
20
+
21
+ #define ge25519_p3 ge25519
22
+
23
+ typedef struct
24
+ {
25
+ fe25519 x;
26
+ fe25519 z;
27
+ fe25519 y;
28
+ fe25519 t;
29
+ } ge25519_p1p1;
30
+
31
+ typedef struct
32
+ {
33
+ fe25519 x;
34
+ fe25519 y;
35
+ fe25519 z;
36
+ } ge25519_p2;
37
+
38
+ typedef struct
39
+ {
40
+ fe25519 x;
41
+ fe25519 y;
42
+ } ge25519_aff;
43
+
44
+
45
+ /* Packed coordinates of the base point */
46
+ const ge25519 ge25519_base = {{{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69,
47
+ 0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}},
48
+ {{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
49
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}},
50
+ {{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
52
+ {{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20,
53
+ 0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}}};
54
+
55
+ /* Multiples of the base point in affine representation */
56
+ static const ge25519_aff ge25519_base_multiples_affine[425] = {
57
+ #include "ge25519_base.data"
58
+ };
59
+
60
+ static void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)
61
+ {
62
+ fe25519_mul(&r->x, &p->x, &p->t);
63
+ fe25519_mul(&r->y, &p->y, &p->z);
64
+ fe25519_mul(&r->z, &p->z, &p->t);
65
+ }
66
+
67
+ static void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)
68
+ {
69
+ p1p1_to_p2((ge25519_p2 *)r, p);
70
+ fe25519_mul(&r->t, &p->x, &p->y);
71
+ }
72
+
73
+ static void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q)
74
+ {
75
+ fe25519 a,b,t1,t2,c,d,e,f,g,h,qt;
76
+ fe25519_mul(&qt, &q->x, &q->y);
77
+ fe25519_sub(&a, &r->y, &r->x); /* A = (Y1-X1)*(Y2-X2) */
78
+ fe25519_add(&b, &r->y, &r->x); /* B = (Y1+X1)*(Y2+X2) */
79
+ fe25519_sub(&t1, &q->y, &q->x);
80
+ fe25519_add(&t2, &q->y, &q->x);
81
+ fe25519_mul(&a, &a, &t1);
82
+ fe25519_mul(&b, &b, &t2);
83
+ fe25519_sub(&e, &b, &a); /* E = B-A */
84
+ fe25519_add(&h, &b, &a); /* H = B+A */
85
+ fe25519_mul(&c, &r->t, &qt); /* C = T1*k*T2 */
86
+ fe25519_mul(&c, &c, &ge25519_ec2d);
87
+ fe25519_add(&d, &r->z, &r->z); /* D = Z1*2 */
88
+ fe25519_sub(&f, &d, &c); /* F = D-C */
89
+ fe25519_add(&g, &d, &c); /* G = D+C */
90
+ fe25519_mul(&r->x, &e, &f);
91
+ fe25519_mul(&r->y, &h, &g);
92
+ fe25519_mul(&r->z, &g, &f);
93
+ fe25519_mul(&r->t, &e, &h);
94
+ }
95
+
96
+ static void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q)
97
+ {
98
+ fe25519 a, b, c, d, t;
99
+
100
+ fe25519_sub(&a, &p->y, &p->x); /* A = (Y1-X1)*(Y2-X2) */
101
+ fe25519_sub(&t, &q->y, &q->x);
102
+ fe25519_mul(&a, &a, &t);
103
+ fe25519_add(&b, &p->x, &p->y); /* B = (Y1+X1)*(Y2+X2) */
104
+ fe25519_add(&t, &q->x, &q->y);
105
+ fe25519_mul(&b, &b, &t);
106
+ fe25519_mul(&c, &p->t, &q->t); /* C = T1*k*T2 */
107
+ fe25519_mul(&c, &c, &ge25519_ec2d);
108
+ fe25519_mul(&d, &p->z, &q->z); /* D = Z1*2*Z2 */
109
+ fe25519_add(&d, &d, &d);
110
+ fe25519_sub(&r->x, &b, &a); /* E = B-A */
111
+ fe25519_sub(&r->t, &d, &c); /* F = D-C */
112
+ fe25519_add(&r->z, &d, &c); /* G = D+C */
113
+ fe25519_add(&r->y, &b, &a); /* H = B+A */
114
+ }
115
+
116
+ /* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */
117
+ static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
118
+ {
119
+ fe25519 a,b,c,d;
120
+ fe25519_square(&a, &p->x);
121
+ fe25519_square(&b, &p->y);
122
+ fe25519_square(&c, &p->z);
123
+ fe25519_add(&c, &c, &c);
124
+ fe25519_neg(&d, &a);
125
+
126
+ fe25519_add(&r->x, &p->x, &p->y);
127
+ fe25519_square(&r->x, &r->x);
128
+ fe25519_sub(&r->x, &r->x, &a);
129
+ fe25519_sub(&r->x, &r->x, &b);
130
+ fe25519_add(&r->z, &d, &b);
131
+ fe25519_sub(&r->t, &r->z, &c);
132
+ fe25519_sub(&r->y, &d, &b);
133
+ }
134
+
135
+ /* Constant-time version of: if(b) r = p */
136
+ static void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)
137
+ {
138
+ fe25519_cmov(&r->x, &p->x, b);
139
+ fe25519_cmov(&r->y, &p->y, b);
140
+ }
141
+
142
+ static unsigned char equal(signed char b,signed char c)
143
+ {
144
+ unsigned char ub = b;
145
+ unsigned char uc = c;
146
+ unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
147
+ crypto_uint32 y = x; /* 0: yes; 1..255: no */
148
+ y -= 1; /* 4294967295: yes; 0..254: no */
149
+ y >>= 31; /* 1: yes; 0: no */
150
+ return y;
151
+ }
152
+
153
+ static unsigned char negative(signed char b)
154
+ {
155
+ unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
156
+ x >>= 63; /* 1: yes; 0: no */
157
+ return x;
158
+ }
159
+
160
+ static void choose_t(ge25519_aff *t, unsigned long long pos, signed char b)
161
+ {
162
+ /* constant time */
163
+ fe25519 v;
164
+ *t = ge25519_base_multiples_affine[5*pos+0];
165
+ cmov_aff(t, &ge25519_base_multiples_affine[5*pos+1],equal(b,1) | equal(b,-1));
166
+ cmov_aff(t, &ge25519_base_multiples_affine[5*pos+2],equal(b,2) | equal(b,-2));
167
+ cmov_aff(t, &ge25519_base_multiples_affine[5*pos+3],equal(b,3) | equal(b,-3));
168
+ cmov_aff(t, &ge25519_base_multiples_affine[5*pos+4],equal(b,-4));
169
+ fe25519_neg(&v, &t->x);
170
+ fe25519_cmov(&t->x, &v, negative(b));
171
+ }
172
+
173
+ static void setneutral(ge25519 *r)
174
+ {
175
+ fe25519_setzero(&r->x);
176
+ fe25519_setone(&r->y);
177
+ fe25519_setone(&r->z);
178
+ fe25519_setzero(&r->t);
179
+ }
180
+
181
+ /* ********************************************************************
182
+ * EXPORTED FUNCTIONS
183
+ ******************************************************************** */
184
+
185
+ /* return 0 on success, -1 otherwise */
186
+ int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])
187
+ {
188
+ unsigned char par;
189
+ fe25519 t, chk, num, den, den2, den4, den6;
190
+ fe25519_setone(&r->z);
191
+ par = p[31] >> 7;
192
+ fe25519_unpack(&r->y, p);
193
+ fe25519_square(&num, &r->y); /* x = y^2 */
194
+ fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */
195
+ fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */
196
+ fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */
197
+
198
+ /* Computation of sqrt(num/den) */
199
+ /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */
200
+ fe25519_square(&den2, &den);
201
+ fe25519_square(&den4, &den2);
202
+ fe25519_mul(&den6, &den4, &den2);
203
+ fe25519_mul(&t, &den6, &num);
204
+ fe25519_mul(&t, &t, &den);
205
+
206
+ fe25519_pow2523(&t, &t);
207
+ /* 2. computation of r->x = t * num * den^3 */
208
+ fe25519_mul(&t, &t, &num);
209
+ fe25519_mul(&t, &t, &den);
210
+ fe25519_mul(&t, &t, &den);
211
+ fe25519_mul(&r->x, &t, &den);
212
+
213
+ /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */
214
+ fe25519_square(&chk, &r->x);
215
+ fe25519_mul(&chk, &chk, &den);
216
+ if (!fe25519_iseq_vartime(&chk, &num))
217
+ fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1);
218
+
219
+ /* 4. Now we have one of the two square roots, except if input was not a square */
220
+ fe25519_square(&chk, &r->x);
221
+ fe25519_mul(&chk, &chk, &den);
222
+ if (!fe25519_iseq_vartime(&chk, &num))
223
+ return -1;
224
+
225
+ /* 5. Choose the desired square root according to parity: */
226
+ if(fe25519_getparity(&r->x) != (1-par))
227
+ fe25519_neg(&r->x, &r->x);
228
+
229
+ fe25519_mul(&r->t, &r->x, &r->y);
230
+ return 0;
231
+ }
232
+
233
+ void ge25519_pack(unsigned char r[32], const ge25519_p3 *p)
234
+ {
235
+ fe25519 tx, ty, zi;
236
+ fe25519_invert(&zi, &p->z);
237
+ fe25519_mul(&tx, &p->x, &zi);
238
+ fe25519_mul(&ty, &p->y, &zi);
239
+ fe25519_pack(r, &ty);
240
+ r[31] ^= fe25519_getparity(&tx) << 7;
241
+ }
242
+
243
+ int ge25519_isneutral_vartime(const ge25519_p3 *p)
244
+ {
245
+ int ret = 1;
246
+ if(!fe25519_iszero(&p->x)) ret = 0;
247
+ if(!fe25519_iseq_vartime(&p->y, &p->z)) ret = 0;
248
+ return ret;
249
+ }
250
+
251
+ /* computes [s1]p1 + [s2]p2 */
252
+ void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2)
253
+ {
254
+ ge25519_p1p1 tp1p1;
255
+ ge25519_p3 pre[16];
256
+ unsigned char b[127];
257
+ int i;
258
+
259
+ /* precomputation s2 s1 */
260
+ setneutral(pre); /* 00 00 */
261
+ pre[1] = *p1; /* 00 01 */
262
+ dbl_p1p1(&tp1p1,(ge25519_p2 *)p1); p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */
263
+ add_p1p1(&tp1p1,&pre[1], &pre[2]); p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */
264
+ pre[4] = *p2; /* 01 00 */
265
+ add_p1p1(&tp1p1,&pre[1], &pre[4]); p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */
266
+ add_p1p1(&tp1p1,&pre[2], &pre[4]); p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */
267
+ add_p1p1(&tp1p1,&pre[3], &pre[4]); p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */
268
+ dbl_p1p1(&tp1p1,(ge25519_p2 *)p2); p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */
269
+ add_p1p1(&tp1p1,&pre[1], &pre[8]); p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */
270
+ dbl_p1p1(&tp1p1,(ge25519_p2 *)&pre[5]); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */
271
+ add_p1p1(&tp1p1,&pre[3], &pre[8]); p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */
272
+ add_p1p1(&tp1p1,&pre[4], &pre[8]); p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */
273
+ add_p1p1(&tp1p1,&pre[1],&pre[12]); p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */
274
+ add_p1p1(&tp1p1,&pre[2],&pre[12]); p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */
275
+ add_p1p1(&tp1p1,&pre[3],&pre[12]); p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */
276
+
277
+ sc25519_2interleave2(b,s1,s2);
278
+
279
+ /* scalar multiplication */
280
+ *r = pre[b[126]];
281
+ for(i=125;i>=0;i--)
282
+ {
283
+ dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
284
+ p1p1_to_p2((ge25519_p2 *) r, &tp1p1);
285
+ dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
286
+ if(b[i]!=0)
287
+ {
288
+ p1p1_to_p3(r, &tp1p1);
289
+ add_p1p1(&tp1p1, r, &pre[b[i]]);
290
+ }
291
+ if(i != 0) p1p1_to_p2((ge25519_p2 *)r, &tp1p1);
292
+ else p1p1_to_p3(r, &tp1p1);
293
+ }
294
+ }
295
+
296
+ void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)
297
+ {
298
+ signed char b[85];
299
+ int i;
300
+ ge25519_aff t;
301
+ sc25519_window3(b,s);
302
+
303
+ choose_t((ge25519_aff *)r, 0, b[0]);
304
+ fe25519_setone(&r->z);
305
+ fe25519_mul(&r->t, &r->x, &r->y);
306
+ for(i=1;i<85;i++)
307
+ {
308
+ choose_t(&t, (unsigned long long) i, b[i]);
309
+ ge25519_mixadd2(r, &t);
310
+ }
311
+ }