diff options
Diffstat (limited to 'nacl/crypto_sign/edwards25519sha512batch/ref')
8 files changed, 963 insertions, 0 deletions
diff --git a/nacl/crypto_sign/edwards25519sha512batch/ref/api.h b/nacl/crypto_sign/edwards25519sha512batch/ref/api.h new file mode 100644 index 00000000..352240c0 --- /dev/null +++ b/nacl/crypto_sign/edwards25519sha512batch/ref/api.h | |||
@@ -0,0 +1,3 @@ | |||
1 | #define CRYPTO_SECRETKEYBYTES 64 | ||
2 | #define CRYPTO_PUBLICKEYBYTES 32 | ||
3 | #define CRYPTO_BYTES 64 | ||
diff --git a/nacl/crypto_sign/edwards25519sha512batch/ref/fe25519.c b/nacl/crypto_sign/edwards25519sha512batch/ref/fe25519.c new file mode 100644 index 00000000..a9f806d2 --- /dev/null +++ b/nacl/crypto_sign/edwards25519sha512batch/ref/fe25519.c | |||
@@ -0,0 +1,345 @@ | |||
1 | #include "fe25519.h" | ||
2 | |||
3 | #define WINDOWSIZE 4 /* Should be 1,2, or 4 */ | ||
4 | #define WINDOWMASK ((1<<WINDOWSIZE)-1) | ||
5 | |||
6 | static void reduce_add_sub(fe25519 *r) | ||
7 | { | ||
8 | crypto_uint32 t; | ||
9 | int i,rep; | ||
10 | |||
11 | for(rep=0;rep<4;rep++) | ||
12 | { | ||
13 | t = r->v[31] >> 7; | ||
14 | r->v[31] &= 127; | ||
15 | t *= 19; | ||
16 | r->v[0] += t; | ||
17 | for(i=0;i<31;i++) | ||
18 | { | ||
19 | t = r->v[i] >> 8; | ||
20 | r->v[i+1] += t; | ||
21 | r->v[i] &= 255; | ||
22 | } | ||
23 | } | ||
24 | } | ||
25 | |||
26 | static void reduce_mul(fe25519 *r) | ||
27 | { | ||
28 | crypto_uint32 t; | ||
29 | int i,rep; | ||
30 | |||
31 | for(rep=0;rep<2;rep++) | ||
32 | { | ||
33 | t = r->v[31] >> 7; | ||
34 | r->v[31] &= 127; | ||
35 | t *= 19; | ||
36 | r->v[0] += t; | ||
37 | for(i=0;i<31;i++) | ||
38 | { | ||
39 | t = r->v[i] >> 8; | ||
40 | r->v[i+1] += t; | ||
41 | r->v[i] &= 255; | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | |||
46 | /* reduction modulo 2^255-19 */ | ||
47 | static void freeze(fe25519 *r) | ||
48 | { | ||
49 | int i; | ||
50 | unsigned int m = (r->v[31] == 127); | ||
51 | for(i=30;i>1;i--) | ||
52 | m *= (r->v[i] == 255); | ||
53 | m *= (r->v[0] >= 237); | ||
54 | |||
55 | r->v[31] -= m*127; | ||
56 | for(i=30;i>0;i--) | ||
57 | r->v[i] -= m*255; | ||
58 | r->v[0] -= m*237; | ||
59 | } | ||
60 | |||
61 | /*freeze input before calling isone*/ | ||
62 | static int isone(const fe25519 *x) | ||
63 | { | ||
64 | int i; | ||
65 | int r = (x->v[0] == 1); | ||
66 | for(i=1;i<32;i++) | ||
67 | r *= (x->v[i] == 0); | ||
68 | return r; | ||
69 | } | ||
70 | |||
71 | /*freeze input before calling iszero*/ | ||
72 | static int iszero(const fe25519 *x) | ||
73 | { | ||
74 | int i; | ||
75 | int r = (x->v[0] == 0); | ||
76 | for(i=1;i<32;i++) | ||
77 | r *= (x->v[i] == 0); | ||
78 | return r; | ||
79 | } | ||
80 | |||
81 | |||
82 | static int issquare(const fe25519 *x) | ||
83 | { | ||
84 | unsigned char e[32] = {0xf6,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f}; /* (p-1)/2 */ | ||
85 | fe25519 t; | ||
86 | |||
87 | fe25519_pow(&t,x,e); | ||
88 | freeze(&t); | ||
89 | return isone(&t) || iszero(&t); | ||
90 | } | ||
91 | |||
92 | void fe25519_unpack(fe25519 *r, const unsigned char x[32]) | ||
93 | { | ||
94 | int i; | ||
95 | for(i=0;i<32;i++) r->v[i] = x[i]; | ||
96 | r->v[31] &= 127; | ||
97 | } | ||
98 | |||
99 | /* Assumes input x being reduced mod 2^255 */ | ||
100 | void fe25519_pack(unsigned char r[32], const fe25519 *x) | ||
101 | { | ||
102 | int i; | ||
103 | for(i=0;i<32;i++) | ||
104 | r[i] = x->v[i]; | ||
105 | |||
106 | /* freeze byte array */ | ||
107 | unsigned int m = (r[31] == 127); /* XXX: some compilers might use branches; fix */ | ||
108 | for(i=30;i>1;i--) | ||
109 | m *= (r[i] == 255); | ||
110 | m *= (r[0] >= 237); | ||
111 | r[31] -= m*127; | ||
112 | for(i=30;i>0;i--) | ||
113 | r[i] -= m*255; | ||
114 | r[0] -= m*237; | ||
115 | } | ||
116 | |||
117 | void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b) | ||
118 | { | ||
119 | unsigned char nb = 1-b; | ||
120 | int i; | ||
121 | for(i=0;i<32;i++) r->v[i] = nb * r->v[i] + b * x->v[i]; | ||
122 | } | ||
123 | |||
124 | unsigned char fe25519_getparity(const fe25519 *x) | ||
125 | { | ||
126 | fe25519 t; | ||
127 | int i; | ||
128 | for(i=0;i<32;i++) t.v[i] = x->v[i]; | ||
129 | freeze(&t); | ||
130 | return t.v[0] & 1; | ||
131 | } | ||
132 | |||
133 | void fe25519_setone(fe25519 *r) | ||
134 | { | ||
135 | int i; | ||
136 | r->v[0] = 1; | ||
137 | for(i=1;i<32;i++) r->v[i]=0; | ||
138 | } | ||
139 | |||
140 | void fe25519_setzero(fe25519 *r) | ||
141 | { | ||
142 | int i; | ||
143 | for(i=0;i<32;i++) r->v[i]=0; | ||
144 | } | ||
145 | |||
146 | void fe25519_neg(fe25519 *r, const fe25519 *x) | ||
147 | { | ||
148 | fe25519 t; | ||
149 | int i; | ||
150 | for(i=0;i<32;i++) t.v[i]=x->v[i]; | ||
151 | fe25519_setzero(r); | ||
152 | fe25519_sub(r, r, &t); | ||
153 | } | ||
154 | |||
155 | void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y) | ||
156 | { | ||
157 | int i; | ||
158 | for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i]; | ||
159 | reduce_add_sub(r); | ||
160 | } | ||
161 | |||
162 | void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y) | ||
163 | { | ||
164 | int i; | ||
165 | crypto_uint32 t[32]; | ||
166 | t[0] = x->v[0] + 0x1da; | ||
167 | t[31] = x->v[31] + 0xfe; | ||
168 | for(i=1;i<31;i++) t[i] = x->v[i] + 0x1fe; | ||
169 | for(i=0;i<32;i++) r->v[i] = t[i] - y->v[i]; | ||
170 | reduce_add_sub(r); | ||
171 | } | ||
172 | |||
173 | void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y) | ||
174 | { | ||
175 | int i,j; | ||
176 | crypto_uint32 t[63]; | ||
177 | for(i=0;i<63;i++)t[i] = 0; | ||
178 | |||
179 | for(i=0;i<32;i++) | ||
180 | for(j=0;j<32;j++) | ||
181 | t[i+j] += x->v[i] * y->v[j]; | ||
182 | |||
183 | for(i=32;i<63;i++) | ||
184 | r->v[i-32] = t[i-32] + 38*t[i]; | ||
185 | r->v[31] = t[31]; /* result now in r[0]...r[31] */ | ||
186 | |||
187 | reduce_mul(r); | ||
188 | } | ||
189 | |||
190 | void fe25519_square(fe25519 *r, const fe25519 *x) | ||
191 | { | ||
192 | fe25519_mul(r, x, x); | ||
193 | } | ||
194 | |||
195 | /*XXX: Make constant time! */ | ||
196 | void fe25519_pow(fe25519 *r, const fe25519 *x, const unsigned char *e) | ||
197 | { | ||
198 | /* | ||
199 | fe25519 g; | ||
200 | fe25519_setone(&g); | ||
201 | int i; | ||
202 | unsigned char j; | ||
203 | for(i=32;i>0;i--) | ||
204 | { | ||
205 | for(j=128;j>0;j>>=1) | ||
206 | { | ||
207 | fe25519_square(&g,&g); | ||
208 | if(e[i-1] & j) | ||
209 | fe25519_mul(&g,&g,x); | ||
210 | } | ||
211 | } | ||
212 | for(i=0;i<32;i++) r->v[i] = g.v[i]; | ||
213 | */ | ||
214 | fe25519 g; | ||
215 | fe25519_setone(&g); | ||
216 | int i,j,k; | ||
217 | fe25519 pre[(1 << WINDOWSIZE)]; | ||
218 | fe25519 t; | ||
219 | unsigned char w; | ||
220 | |||
221 | // Precomputation | ||
222 | fe25519_setone(pre); | ||
223 | pre[1] = *x; | ||
224 | for(i=2;i<(1<<WINDOWSIZE);i+=2) | ||
225 | { | ||
226 | fe25519_square(pre+i, pre+i/2); | ||
227 | fe25519_mul(pre+i+1, pre+i, pre+1); | ||
228 | } | ||
229 | |||
230 | // Fixed-window scalar multiplication | ||
231 | for(i=32;i>0;i--) | ||
232 | { | ||
233 | for(j=8-WINDOWSIZE;j>=0;j-=WINDOWSIZE) | ||
234 | { | ||
235 | for(k=0;k<WINDOWSIZE;k++) | ||
236 | fe25519_square(&g, &g); | ||
237 | // Cache-timing resistant loading of precomputed value: | ||
238 | w = (e[i-1]>>j) & WINDOWMASK; | ||
239 | t = pre[0]; | ||
240 | for(k=1;k<(1<<WINDOWSIZE);k++) | ||
241 | fe25519_cmov(&t, &pre[k], k==w); | ||
242 | fe25519_mul(&g, &g, &t); | ||
243 | } | ||
244 | } | ||
245 | *r = g; | ||
246 | } | ||
247 | |||
248 | /* Return 0 on success, 1 otherwise */ | ||
249 | int fe25519_sqrt_vartime(fe25519 *r, const fe25519 *x, unsigned char parity) | ||
250 | { | ||
251 | /* See HAC, Alg. 3.37 */ | ||
252 | if (!issquare(x)) return -1; | ||
253 | unsigned char e[32] = {0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f}; /* (p-1)/4 */ | ||
254 | unsigned char e2[32] = {0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f}; /* (p+3)/8 */ | ||
255 | unsigned char e3[32] = {0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0f}; /* (p-5)/8 */ | ||
256 | fe25519 p = {{0}}; | ||
257 | fe25519 d; | ||
258 | int i; | ||
259 | fe25519_pow(&d,x,e); | ||
260 | freeze(&d); | ||
261 | if(isone(&d)) | ||
262 | fe25519_pow(r,x,e2); | ||
263 | else | ||
264 | { | ||
265 | for(i=0;i<32;i++) | ||
266 | d.v[i] = 4*x->v[i]; | ||
267 | fe25519_pow(&d,&d,e3); | ||
268 | for(i=0;i<32;i++) | ||
269 | r->v[i] = 2*x->v[i]; | ||
270 | fe25519_mul(r,r,&d); | ||
271 | } | ||
272 | freeze(r); | ||
273 | if((r->v[0] & 1) != (parity & 1)) | ||
274 | { | ||
275 | fe25519_sub(r,&p,r); | ||
276 | } | ||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | void fe25519_invert(fe25519 *r, const fe25519 *x) | ||
281 | { | ||
282 | fe25519 z2; | ||
283 | fe25519 z9; | ||
284 | fe25519 z11; | ||
285 | fe25519 z2_5_0; | ||
286 | fe25519 z2_10_0; | ||
287 | fe25519 z2_20_0; | ||
288 | fe25519 z2_50_0; | ||
289 | fe25519 z2_100_0; | ||
290 | fe25519 t0; | ||
291 | fe25519 t1; | ||
292 | int i; | ||
293 | |||
294 | /* 2 */ fe25519_square(&z2,x); | ||
295 | /* 4 */ fe25519_square(&t1,&z2); | ||
296 | /* 8 */ fe25519_square(&t0,&t1); | ||
297 | /* 9 */ fe25519_mul(&z9,&t0,x); | ||
298 | /* 11 */ fe25519_mul(&z11,&z9,&z2); | ||
299 | /* 22 */ fe25519_square(&t0,&z11); | ||
300 | /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t0,&z9); | ||
301 | |||
302 | /* 2^6 - 2^1 */ fe25519_square(&t0,&z2_5_0); | ||
303 | /* 2^7 - 2^2 */ fe25519_square(&t1,&t0); | ||
304 | /* 2^8 - 2^3 */ fe25519_square(&t0,&t1); | ||
305 | /* 2^9 - 2^4 */ fe25519_square(&t1,&t0); | ||
306 | /* 2^10 - 2^5 */ fe25519_square(&t0,&t1); | ||
307 | /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t0,&z2_5_0); | ||
308 | |||
309 | /* 2^11 - 2^1 */ fe25519_square(&t0,&z2_10_0); | ||
310 | /* 2^12 - 2^2 */ fe25519_square(&t1,&t0); | ||
311 | /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } | ||
312 | /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t1,&z2_10_0); | ||
313 | |||
314 | /* 2^21 - 2^1 */ fe25519_square(&t0,&z2_20_0); | ||
315 | /* 2^22 - 2^2 */ fe25519_square(&t1,&t0); | ||
316 | /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } | ||
317 | /* 2^40 - 2^0 */ fe25519_mul(&t0,&t1,&z2_20_0); | ||
318 | |||
319 | /* 2^41 - 2^1 */ fe25519_square(&t1,&t0); | ||
320 | /* 2^42 - 2^2 */ fe25519_square(&t0,&t1); | ||
321 | /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); } | ||
322 | /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0); | ||
323 | |||
324 | /* 2^51 - 2^1 */ fe25519_square(&t0,&z2_50_0); | ||
325 | /* 2^52 - 2^2 */ fe25519_square(&t1,&t0); | ||
326 | /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } | ||
327 | /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t1,&z2_50_0); | ||
328 | |||
329 | /* 2^101 - 2^1 */ fe25519_square(&t1,&z2_100_0); | ||
330 | /* 2^102 - 2^2 */ fe25519_square(&t0,&t1); | ||
331 | /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fe25519_square(&t1,&t0); fe25519_square(&t0,&t1); } | ||
332 | /* 2^200 - 2^0 */ fe25519_mul(&t1,&t0,&z2_100_0); | ||
333 | |||
334 | /* 2^201 - 2^1 */ fe25519_square(&t0,&t1); | ||
335 | /* 2^202 - 2^2 */ fe25519_square(&t1,&t0); | ||
336 | /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fe25519_square(&t0,&t1); fe25519_square(&t1,&t0); } | ||
337 | /* 2^250 - 2^0 */ fe25519_mul(&t0,&t1,&z2_50_0); | ||
338 | |||
339 | /* 2^251 - 2^1 */ fe25519_square(&t1,&t0); | ||
340 | /* 2^252 - 2^2 */ fe25519_square(&t0,&t1); | ||
341 | /* 2^253 - 2^3 */ fe25519_square(&t1,&t0); | ||
342 | /* 2^254 - 2^4 */ fe25519_square(&t0,&t1); | ||
343 | /* 2^255 - 2^5 */ fe25519_square(&t1,&t0); | ||
344 | /* 2^255 - 21 */ fe25519_mul(r,&t1,&z11); | ||
345 | } | ||
diff --git a/nacl/crypto_sign/edwards25519sha512batch/ref/fe25519.h b/nacl/crypto_sign/edwards25519sha512batch/ref/fe25519.h new file mode 100644 index 00000000..e07ddba7 --- /dev/null +++ b/nacl/crypto_sign/edwards25519sha512batch/ref/fe25519.h | |||
@@ -0,0 +1,54 @@ | |||
1 | #ifndef FE25519_H | ||
2 | #define FE25519_H | ||
3 | |||
4 | #define fe25519 crypto_sign_edwards25519sha512batch_fe25519 | ||
5 | #define fe25519_unpack crypto_sign_edwards25519sha512batch_fe25519_unpack | ||
6 | #define fe25519_pack crypto_sign_edwards25519sha512batch_fe25519_pack | ||
7 | #define fe25519_cmov crypto_sign_edwards25519sha512batch_fe25519_cmov | ||
8 | #define fe25519_setone crypto_sign_edwards25519sha512batch_fe25519_setone | ||
9 | #define fe25519_setzero crypto_sign_edwards25519sha512batch_fe25519_setzero | ||
10 | #define fe25519_neg crypto_sign_edwards25519sha512batch_fe25519_neg | ||
11 | #define fe25519_getparity crypto_sign_edwards25519sha512batch_fe25519_getparity | ||
12 | #define fe25519_add crypto_sign_edwards25519sha512batch_fe25519_add | ||
13 | #define fe25519_sub crypto_sign_edwards25519sha512batch_fe25519_sub | ||
14 | #define fe25519_mul crypto_sign_edwards25519sha512batch_fe25519_mul | ||
15 | #define fe25519_square crypto_sign_edwards25519sha512batch_fe25519_square | ||
16 | #define fe25519_pow crypto_sign_edwards25519sha512batch_fe25519_pow | ||
17 | #define fe25519_sqrt_vartime crypto_sign_edwards25519sha512batch_fe25519_sqrt_vartime | ||
18 | #define fe25519_invert crypto_sign_edwards25519sha512batch_fe25519_invert | ||
19 | |||
20 | #include "crypto_uint32.h" | ||
21 | |||
22 | typedef struct { | ||
23 | crypto_uint32 v[32]; | ||
24 | } fe25519; | ||
25 | |||
26 | void fe25519_unpack(fe25519 *r, const unsigned char x[32]); | ||
27 | |||
28 | void fe25519_pack(unsigned char r[32], const fe25519 *x); | ||
29 | |||
30 | void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b); | ||
31 | |||
32 | void fe25519_setone(fe25519 *r); | ||
33 | |||
34 | void fe25519_setzero(fe25519 *r); | ||
35 | |||
36 | void fe25519_neg(fe25519 *r, const fe25519 *x); | ||
37 | |||
38 | unsigned char fe25519_getparity(const fe25519 *x); | ||
39 | |||
40 | void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y); | ||
41 | |||
42 | void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y); | ||
43 | |||
44 | void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y); | ||
45 | |||
46 | void fe25519_square(fe25519 *r, const fe25519 *x); | ||
47 | |||
48 | void fe25519_pow(fe25519 *r, const fe25519 *x, const unsigned char *e); | ||
49 | |||
50 | int fe25519_sqrt_vartime(fe25519 *r, const fe25519 *x, unsigned char parity); | ||
51 | |||
52 | void fe25519_invert(fe25519 *r, const fe25519 *x); | ||
53 | |||
54 | #endif | ||
diff --git a/nacl/crypto_sign/edwards25519sha512batch/ref/ge25519.c b/nacl/crypto_sign/edwards25519sha512batch/ref/ge25519.c new file mode 100644 index 00000000..a57b8f3c --- /dev/null +++ b/nacl/crypto_sign/edwards25519sha512batch/ref/ge25519.c | |||
@@ -0,0 +1,227 @@ | |||
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 | typedef struct | ||
12 | { | ||
13 | fe25519 x; | ||
14 | fe25519 z; | ||
15 | fe25519 y; | ||
16 | fe25519 t; | ||
17 | } ge25519_p1p1; | ||
18 | |||
19 | typedef struct | ||
20 | { | ||
21 | fe25519 x; | ||
22 | fe25519 y; | ||
23 | fe25519 z; | ||
24 | } ge25519_p2; | ||
25 | |||
26 | #define ge25519_p3 ge25519 | ||
27 | |||
28 | /* Windowsize for fixed-window scalar multiplication */ | ||
29 | #define WINDOWSIZE 2 /* Should be 1,2, or 4 */ | ||
30 | #define WINDOWMASK ((1<<WINDOWSIZE)-1) | ||
31 | |||
32 | /* packed parameter d in the Edwards curve equation */ | ||
33 | static const unsigned char ecd[32] = {0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75, 0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00, | ||
34 | 0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C, 0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}; | ||
35 | |||
36 | /* Packed coordinates of the base point */ | ||
37 | static const unsigned char ge25519_base_x[32] = {0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9, 0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69, | ||
38 | 0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0, 0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}; | ||
39 | static const unsigned char ge25519_base_y[32] = {0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, | ||
40 | 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}; | ||
41 | static const unsigned char ge25519_base_z[32] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | ||
42 | static const unsigned char ge25519_base_t[32] = {0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D, 0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20, | ||
43 | 0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66, 0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}; | ||
44 | |||
45 | /* Packed coordinates of the neutral element */ | ||
46 | static const unsigned char ge25519_neutral_x[32] = {0}; | ||
47 | static const unsigned char ge25519_neutral_y[32] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | ||
48 | static const unsigned char ge25519_neutral_z[32] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | ||
49 | static const unsigned char ge25519_neutral_t[32] = {0}; | ||
50 | |||
51 | static void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p) | ||
52 | { | ||
53 | fe25519_mul(&r->x, &p->x, &p->t); | ||
54 | fe25519_mul(&r->y, &p->y, &p->z); | ||
55 | fe25519_mul(&r->z, &p->z, &p->t); | ||
56 | } | ||
57 | |||
58 | static void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p) | ||
59 | { | ||
60 | p1p1_to_p2((ge25519_p2 *)r, p); | ||
61 | fe25519_mul(&r->t, &p->x, &p->y); | ||
62 | } | ||
63 | |||
64 | /* Constant-time version of: if(b) r = p */ | ||
65 | static void cmov_p3(ge25519_p3 *r, const ge25519_p3 *p, unsigned char b) | ||
66 | { | ||
67 | fe25519_cmov(&r->x, &p->x, b); | ||
68 | fe25519_cmov(&r->y, &p->y, b); | ||
69 | fe25519_cmov(&r->z, &p->z, b); | ||
70 | fe25519_cmov(&r->t, &p->t, b); | ||
71 | } | ||
72 | |||
73 | /* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */ | ||
74 | static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p) | ||
75 | { | ||
76 | fe25519 a,b,c,d; | ||
77 | fe25519_square(&a, &p->x); | ||
78 | fe25519_square(&b, &p->y); | ||
79 | fe25519_square(&c, &p->z); | ||
80 | fe25519_add(&c, &c, &c); | ||
81 | fe25519_neg(&d, &a); | ||
82 | |||
83 | fe25519_add(&r->x, &p->x, &p->y); | ||
84 | fe25519_square(&r->x, &r->x); | ||
85 | fe25519_sub(&r->x, &r->x, &a); | ||
86 | fe25519_sub(&r->x, &r->x, &b); | ||
87 | fe25519_add(&r->z, &d, &b); | ||
88 | fe25519_sub(&r->t, &r->z, &c); | ||
89 | fe25519_sub(&r->y, &d, &b); | ||
90 | } | ||
91 | |||
92 | static void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q) | ||
93 | { | ||
94 | fe25519 a, b, c, d, t, fd; | ||
95 | fe25519_unpack(&fd, ecd); | ||
96 | |||
97 | fe25519_sub(&a, &p->y, &p->x); // A = (Y1-X1)*(Y2-X2) | ||
98 | fe25519_sub(&t, &q->y, &q->x); | ||
99 | fe25519_mul(&a, &a, &t); | ||
100 | fe25519_add(&b, &p->x, &p->y); // B = (Y1+X1)*(Y2+X2) | ||
101 | fe25519_add(&t, &q->x, &q->y); | ||
102 | fe25519_mul(&b, &b, &t); | ||
103 | fe25519_mul(&c, &p->t, &q->t); //C = T1*k*T2 | ||
104 | fe25519_mul(&c, &c, &fd); | ||
105 | fe25519_add(&c, &c, &c); //XXX: Can save this addition by precomputing 2*ecd | ||
106 | fe25519_mul(&d, &p->z, &q->z); //D = Z1*2*Z2 | ||
107 | fe25519_add(&d, &d, &d); | ||
108 | fe25519_sub(&r->x, &b, &a); // E = B-A | ||
109 | fe25519_sub(&r->t, &d, &c); // F = D-C | ||
110 | fe25519_add(&r->z, &d, &c); // G = D+C | ||
111 | fe25519_add(&r->y, &b, &a); // H = B+A | ||
112 | } | ||
113 | |||
114 | /* ******************************************************************** | ||
115 | * EXPORTED FUNCTIONS | ||
116 | ******************************************************************** */ | ||
117 | |||
118 | /* return 0 on success, -1 otherwise */ | ||
119 | int ge25519_unpack_vartime(ge25519_p3 *r, const unsigned char p[32]) | ||
120 | { | ||
121 | int ret; | ||
122 | fe25519 t, fd; | ||
123 | fe25519_setone(&r->z); | ||
124 | fe25519_unpack(&fd, ecd); | ||
125 | unsigned char par = p[31] >> 7; | ||
126 | fe25519_unpack(&r->y, p); | ||
127 | fe25519_square(&r->x, &r->y); | ||
128 | fe25519_mul(&t, &r->x, &fd); | ||
129 | fe25519_sub(&r->x, &r->x, &r->z); | ||
130 | fe25519_add(&t, &r->z, &t); | ||
131 | fe25519_invert(&t, &t); | ||
132 | fe25519_mul(&r->x, &r->x, &t); | ||
133 | ret = fe25519_sqrt_vartime(&r->x, &r->x, par); | ||
134 | fe25519_mul(&r->t, &r->x, &r->y); | ||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | void ge25519_pack(unsigned char r[32], const ge25519_p3 *p) | ||
139 | { | ||
140 | fe25519 tx, ty, zi; | ||
141 | fe25519_invert(&zi, &p->z); | ||
142 | fe25519_mul(&tx, &p->x, &zi); | ||
143 | fe25519_mul(&ty, &p->y, &zi); | ||
144 | fe25519_pack(r, &ty); | ||
145 | r[31] ^= fe25519_getparity(&tx) << 7; | ||
146 | } | ||
147 | |||
148 | void ge25519_add(ge25519_p3 *r, const ge25519_p3 *p, const ge25519_p3 *q) | ||
149 | { | ||
150 | ge25519_p1p1 grp1p1; | ||
151 | add_p1p1(&grp1p1, p, q); | ||
152 | p1p1_to_p3(r, &grp1p1); | ||
153 | } | ||
154 | |||
155 | void ge25519_double(ge25519_p3 *r, const ge25519_p3 *p) | ||
156 | { | ||
157 | ge25519_p1p1 grp1p1; | ||
158 | dbl_p1p1(&grp1p1, (ge25519_p2 *)p); | ||
159 | p1p1_to_p3(r, &grp1p1); | ||
160 | } | ||
161 | |||
162 | void ge25519_scalarmult(ge25519_p3 *r, const ge25519_p3 *p, const sc25519 *s) | ||
163 | { | ||
164 | int i,j,k; | ||
165 | ge25519_p3 g; | ||
166 | fe25519_unpack(&g.x, ge25519_neutral_x); | ||
167 | fe25519_unpack(&g.y, ge25519_neutral_y); | ||
168 | fe25519_unpack(&g.z, ge25519_neutral_z); | ||
169 | fe25519_unpack(&g.t, ge25519_neutral_t); | ||
170 | |||
171 | ge25519_p3 pre[(1 << WINDOWSIZE)]; | ||
172 | ge25519_p3 t; | ||
173 | ge25519_p1p1 tp1p1; | ||
174 | unsigned char w; | ||
175 | unsigned char sb[32]; | ||
176 | sc25519_to32bytes(sb, s); | ||
177 | |||
178 | // Precomputation | ||
179 | pre[0] = g; | ||
180 | pre[1] = *p; | ||
181 | for(i=2;i<(1<<WINDOWSIZE);i+=2) | ||
182 | { | ||
183 | dbl_p1p1(&tp1p1, (ge25519_p2 *)(pre+i/2)); | ||
184 | p1p1_to_p3(pre+i, &tp1p1); | ||
185 | add_p1p1(&tp1p1, pre+i, pre+1); | ||
186 | p1p1_to_p3(pre+i+1, &tp1p1); | ||
187 | } | ||
188 | |||
189 | // Fixed-window scalar multiplication | ||
190 | for(i=32;i>0;i--) | ||
191 | { | ||
192 | for(j=8-WINDOWSIZE;j>=0;j-=WINDOWSIZE) | ||
193 | { | ||
194 | for(k=0;k<WINDOWSIZE-1;k++) | ||
195 | { | ||
196 | dbl_p1p1(&tp1p1, (ge25519_p2 *)&g); | ||
197 | p1p1_to_p2((ge25519_p2 *)&g, &tp1p1); | ||
198 | } | ||
199 | dbl_p1p1(&tp1p1, (ge25519_p2 *)&g); | ||
200 | p1p1_to_p3(&g, &tp1p1); | ||
201 | // Cache-timing resistant loading of precomputed value: | ||
202 | w = (sb[i-1]>>j) & WINDOWMASK; | ||
203 | t = pre[0]; | ||
204 | for(k=1;k<(1<<WINDOWSIZE);k++) | ||
205 | cmov_p3(&t, &pre[k], k==w); | ||
206 | |||
207 | add_p1p1(&tp1p1, &g, &t); | ||
208 | if(j != 0) p1p1_to_p2((ge25519_p2 *)&g, &tp1p1); | ||
209 | else p1p1_to_p3(&g, &tp1p1); /* convert to p3 representation at the end */ | ||
210 | } | ||
211 | } | ||
212 | r->x = g.x; | ||
213 | r->y = g.y; | ||
214 | r->z = g.z; | ||
215 | r->t = g.t; | ||
216 | } | ||
217 | |||
218 | void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s) | ||
219 | { | ||
220 | /* XXX: Better algorithm for known-base-point scalar multiplication */ | ||
221 | ge25519_p3 t; | ||
222 | fe25519_unpack(&t.x, ge25519_base_x); | ||
223 | fe25519_unpack(&t.y, ge25519_base_y); | ||
224 | fe25519_unpack(&t.z, ge25519_base_z); | ||
225 | fe25519_unpack(&t.t, ge25519_base_t); | ||
226 | ge25519_scalarmult(r, &t, s); | ||
227 | } | ||
diff --git a/nacl/crypto_sign/edwards25519sha512batch/ref/ge25519.h b/nacl/crypto_sign/edwards25519sha512batch/ref/ge25519.h new file mode 100644 index 00000000..49ad163a --- /dev/null +++ b/nacl/crypto_sign/edwards25519sha512batch/ref/ge25519.h | |||
@@ -0,0 +1,34 @@ | |||
1 | #ifndef GE25519_H | ||
2 | #define GE25519_H | ||
3 | |||
4 | #include "fe25519.h" | ||
5 | #include "sc25519.h" | ||
6 | |||
7 | #define ge25519 crypto_sign_edwards25519sha512batch_ge25519 | ||
8 | #define ge25519_unpack_vartime crypto_sign_edwards25519sha512batch_ge25519_unpack_vartime | ||
9 | #define ge25519_pack crypto_sign_edwards25519sha512batch_ge25519_pack | ||
10 | #define ge25519_add crypto_sign_edwards25519sha512batch_ge25519_add | ||
11 | #define ge25519_double crypto_sign_edwards25519sha512batch_ge25519_double | ||
12 | #define ge25519_scalarmult crypto_sign_edwards25519sha512batch_ge25519_scalarmult | ||
13 | #define ge25519_scalarmult_base crypto_sign_edwards25519sha512batch_ge25519_scalarmult_base | ||
14 | |||
15 | typedef struct { | ||
16 | fe25519 x; | ||
17 | fe25519 y; | ||
18 | fe25519 z; | ||
19 | fe25519 t; | ||
20 | } ge25519; | ||
21 | |||
22 | int ge25519_unpack_vartime(ge25519 *r, const unsigned char p[32]); | ||
23 | |||
24 | void ge25519_pack(unsigned char r[32], const ge25519 *p); | ||
25 | |||
26 | void ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q); | ||
27 | |||
28 | void ge25519_double(ge25519 *r, const ge25519 *p); | ||
29 | |||
30 | void ge25519_scalarmult(ge25519 *r, const ge25519 *p, const sc25519 *s); | ||
31 | |||
32 | void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s); | ||
33 | |||
34 | #endif | ||
diff --git a/nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.c b/nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.c new file mode 100644 index 00000000..5f27eb1b --- /dev/null +++ b/nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.c | |||
@@ -0,0 +1,146 @@ | |||
1 | #include "sc25519.h" | ||
2 | |||
3 | /*Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 */ | ||
4 | |||
5 | static const crypto_uint32 m[32] = {0xED, 0xD3, 0xF5, 0x5C, 0x1A, 0x63, 0x12, 0x58, 0xD6, 0x9C, 0xF7, 0xA2, 0xDE, 0xF9, 0xDE, 0x14, | ||
6 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}; | ||
7 | |||
8 | static const crypto_uint32 mu[33] = {0x1B, 0x13, 0x2C, 0x0A, 0xA3, 0xE5, 0x9C, 0xED, 0xA7, 0x29, 0x63, 0x08, 0x5D, 0x21, 0x06, 0x21, | ||
9 | 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F}; | ||
10 | |||
11 | /* Reduce coefficients of r before calling reduce_add_sub */ | ||
12 | static void reduce_add_sub(sc25519 *r) | ||
13 | { | ||
14 | int i, b, pb=0, nb; | ||
15 | unsigned char t[32]; | ||
16 | |||
17 | for(i=0;i<32;i++) | ||
18 | { | ||
19 | b = (r->v[i]<pb+m[i]); | ||
20 | t[i] = r->v[i]-pb-m[i]+b*256; | ||
21 | pb = b; | ||
22 | } | ||
23 | nb = 1-b; | ||
24 | for(i=0;i<32;i++) | ||
25 | r->v[i] = r->v[i]*b + t[i]*nb; | ||
26 | } | ||
27 | |||
28 | /* Reduce coefficients of x before calling barrett_reduce */ | ||
29 | static void barrett_reduce(sc25519 *r, const crypto_uint32 x[64]) | ||
30 | { | ||
31 | /* See HAC, Alg. 14.42 */ | ||
32 | int i,j; | ||
33 | crypto_uint32 q2[66] = {0}; | ||
34 | crypto_uint32 *q3 = q2 + 33; | ||
35 | crypto_uint32 r1[33]; | ||
36 | crypto_uint32 r2[33] = {0}; | ||
37 | crypto_uint32 carry; | ||
38 | int b, pb=0; | ||
39 | |||
40 | for(i=0;i<33;i++) | ||
41 | for(j=0;j<33;j++) | ||
42 | if(i+j >= 31) q2[i+j] += mu[i]*x[j+31]; | ||
43 | carry = q2[31] >> 8; | ||
44 | q2[32] += carry; | ||
45 | carry = q2[32] >> 8; | ||
46 | q2[33] += carry; | ||
47 | |||
48 | for(i=0;i<33;i++)r1[i] = x[i]; | ||
49 | for(i=0;i<32;i++) | ||
50 | for(j=0;j<33;j++) | ||
51 | if(i+j < 33) r2[i+j] += m[i]*q3[j]; | ||
52 | |||
53 | for(i=0;i<32;i++) | ||
54 | { | ||
55 | carry = r2[i] >> 8; | ||
56 | r2[i+1] += carry; | ||
57 | r2[i] &= 0xff; | ||
58 | } | ||
59 | |||
60 | for(i=0;i<32;i++) | ||
61 | { | ||
62 | b = (r1[i]<pb+r2[i]); | ||
63 | r->v[i] = r1[i]-pb-r2[i]+b*256; | ||
64 | pb = b; | ||
65 | } | ||
66 | |||
67 | /* XXX: Can it really happen that r<0?, See HAC, Alg 14.42, Step 3 | ||
68 | * If so: Handle it here! | ||
69 | */ | ||
70 | |||
71 | reduce_add_sub(r); | ||
72 | reduce_add_sub(r); | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | static int iszero(const sc25519 *x) | ||
77 | { | ||
78 | // Implement | ||
79 | return 0; | ||
80 | } | ||
81 | */ | ||
82 | |||
83 | void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]) | ||
84 | { | ||
85 | int i; | ||
86 | crypto_uint32 t[64] = {0}; | ||
87 | for(i=0;i<32;i++) t[i] = x[i]; | ||
88 | barrett_reduce(r, t); | ||
89 | } | ||
90 | |||
91 | void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]) | ||
92 | { | ||
93 | int i; | ||
94 | crypto_uint32 t[64] = {0}; | ||
95 | for(i=0;i<64;i++) t[i] = x[i]; | ||
96 | barrett_reduce(r, t); | ||
97 | } | ||
98 | |||
99 | /* XXX: What we actually want for crypto_group is probably just something like | ||
100 | * void sc25519_frombytes(sc25519 *r, const unsigned char *x, size_t xlen) | ||
101 | */ | ||
102 | |||
103 | void sc25519_to32bytes(unsigned char r[32], const sc25519 *x) | ||
104 | { | ||
105 | int i; | ||
106 | for(i=0;i<32;i++) r[i] = x->v[i]; | ||
107 | } | ||
108 | |||
109 | void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y) | ||
110 | { | ||
111 | int i, carry; | ||
112 | for(i=0;i<32;i++) r->v[i] = x->v[i] + y->v[i]; | ||
113 | for(i=0;i<31;i++) | ||
114 | { | ||
115 | carry = r->v[i] >> 8; | ||
116 | r->v[i+1] += carry; | ||
117 | r->v[i] &= 0xff; | ||
118 | } | ||
119 | reduce_add_sub(r); | ||
120 | } | ||
121 | |||
122 | void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y) | ||
123 | { | ||
124 | int i,j,carry; | ||
125 | crypto_uint32 t[64]; | ||
126 | for(i=0;i<64;i++)t[i] = 0; | ||
127 | |||
128 | for(i=0;i<32;i++) | ||
129 | for(j=0;j<32;j++) | ||
130 | t[i+j] += x->v[i] * y->v[j]; | ||
131 | |||
132 | /* Reduce coefficients */ | ||
133 | for(i=0;i<63;i++) | ||
134 | { | ||
135 | carry = t[i] >> 8; | ||
136 | t[i+1] += carry; | ||
137 | t[i] &= 0xff; | ||
138 | } | ||
139 | |||
140 | barrett_reduce(r, t); | ||
141 | } | ||
142 | |||
143 | void sc25519_square(sc25519 *r, const sc25519 *x) | ||
144 | { | ||
145 | sc25519_mul(r, x, x); | ||
146 | } | ||
diff --git a/nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.h b/nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.h new file mode 100644 index 00000000..48584a85 --- /dev/null +++ b/nacl/crypto_sign/edwards25519sha512batch/ref/sc25519.h | |||
@@ -0,0 +1,51 @@ | |||
1 | #ifndef SC25519_H | ||
2 | #define SC25519_H | ||
3 | |||
4 | #define sc25519 crypto_sign_edwards25519sha512batch_sc25519 | ||
5 | #define sc25519_from32bytes crypto_sign_edwards25519sha512batch_sc25519_from32bytes | ||
6 | #define sc25519_from64bytes crypto_sign_edwards25519sha512batch_sc25519_from64bytes | ||
7 | #define sc25519_to32bytes crypto_sign_edwards25519sha512batch_sc25519_to32bytes | ||
8 | #define sc25519_pack crypto_sign_edwards25519sha512batch_sc25519_pack | ||
9 | #define sc25519_getparity crypto_sign_edwards25519sha512batch_sc25519_getparity | ||
10 | #define sc25519_setone crypto_sign_edwards25519sha512batch_sc25519_setone | ||
11 | #define sc25519_setzero crypto_sign_edwards25519sha512batch_sc25519_setzero | ||
12 | #define sc25519_neg crypto_sign_edwards25519sha512batch_sc25519_neg | ||
13 | #define sc25519_add crypto_sign_edwards25519sha512batch_sc25519_add | ||
14 | #define sc25519_sub crypto_sign_edwards25519sha512batch_sc25519_sub | ||
15 | #define sc25519_mul crypto_sign_edwards25519sha512batch_sc25519_mul | ||
16 | #define sc25519_square crypto_sign_edwards25519sha512batch_sc25519_square | ||
17 | #define sc25519_invert crypto_sign_edwards25519sha512batch_sc25519_invert | ||
18 | |||
19 | #include "crypto_uint32.h" | ||
20 | |||
21 | typedef struct { | ||
22 | crypto_uint32 v[32]; | ||
23 | } sc25519; | ||
24 | |||
25 | void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]); | ||
26 | |||
27 | void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]); | ||
28 | |||
29 | void sc25519_to32bytes(unsigned char r[32], const sc25519 *x); | ||
30 | |||
31 | void sc25519_pack(unsigned char r[32], const sc25519 *x); | ||
32 | |||
33 | unsigned char sc25519_getparity(const sc25519 *x); | ||
34 | |||
35 | void sc25519_setone(sc25519 *r); | ||
36 | |||
37 | void sc25519_setzero(sc25519 *r); | ||
38 | |||
39 | void sc25519_neg(sc25519 *r, const sc25519 *x); | ||
40 | |||
41 | void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y); | ||
42 | |||
43 | void sc25519_sub(sc25519 *r, const sc25519 *x, const sc25519 *y); | ||
44 | |||
45 | void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y); | ||
46 | |||
47 | void sc25519_square(sc25519 *r, const sc25519 *x); | ||
48 | |||
49 | void sc25519_invert(sc25519 *r, const sc25519 *x); | ||
50 | |||
51 | #endif | ||
diff --git a/nacl/crypto_sign/edwards25519sha512batch/ref/sign.c b/nacl/crypto_sign/edwards25519sha512batch/ref/sign.c new file mode 100644 index 00000000..f40e548b --- /dev/null +++ b/nacl/crypto_sign/edwards25519sha512batch/ref/sign.c | |||
@@ -0,0 +1,103 @@ | |||
1 | #include "api.h" | ||
2 | #include "crypto_sign.h" | ||
3 | #include "crypto_hash_sha512.h" | ||
4 | #include "randombytes.h" | ||
5 | #include "crypto_verify_32.h" | ||
6 | |||
7 | #include "ge25519.h" | ||
8 | |||
9 | int crypto_sign_keypair( | ||
10 | unsigned char *pk, | ||
11 | unsigned char *sk | ||
12 | ) | ||
13 | { | ||
14 | sc25519 scsk; | ||
15 | ge25519 gepk; | ||
16 | |||
17 | randombytes(sk, 32); | ||
18 | crypto_hash_sha512(sk, sk, 32); | ||
19 | sk[0] &= 248; | ||
20 | sk[31] &= 127; | ||
21 | sk[31] |= 64; | ||
22 | |||
23 | sc25519_from32bytes(&scsk,sk); | ||
24 | |||
25 | ge25519_scalarmult_base(&gepk, &scsk); | ||
26 | ge25519_pack(pk, &gepk); | ||
27 | return 0; | ||
28 | } | ||
29 | |||
30 | int crypto_sign( | ||
31 | unsigned char *sm,unsigned long long *smlen, | ||
32 | const unsigned char *m,unsigned long long mlen, | ||
33 | const unsigned char *sk | ||
34 | ) | ||
35 | { | ||
36 | sc25519 sck, scs, scsk; | ||
37 | ge25519 ger; | ||
38 | unsigned char r[32]; | ||
39 | unsigned char s[32]; | ||
40 | unsigned long long i; | ||
41 | unsigned char hmg[crypto_hash_sha512_BYTES]; | ||
42 | unsigned char hmr[crypto_hash_sha512_BYTES]; | ||
43 | |||
44 | *smlen = mlen+64; | ||
45 | for(i=0;i<mlen;i++) | ||
46 | sm[32 + i] = m[i]; | ||
47 | for(i=0;i<32;i++) | ||
48 | sm[i] = sk[32+i]; | ||
49 | crypto_hash_sha512(hmg, sm, mlen+32); /* Generate k as h(m,sk[32],...,sk[63]) */ | ||
50 | |||
51 | sc25519_from64bytes(&sck, hmg); | ||
52 | ge25519_scalarmult_base(&ger, &sck); | ||
53 | ge25519_pack(r, &ger); | ||
54 | |||
55 | for(i=0;i<32;i++) | ||
56 | sm[i] = r[i]; | ||
57 | |||
58 | crypto_hash_sha512(hmr, sm, mlen+32); /* Compute h(m,r) */ | ||
59 | sc25519_from64bytes(&scs, hmr); | ||
60 | sc25519_mul(&scs, &scs, &sck); | ||
61 | |||
62 | sc25519_from32bytes(&scsk, sk); | ||
63 | sc25519_add(&scs, &scs, &scsk); | ||
64 | |||
65 | sc25519_to32bytes(s,&scs); /* cat s */ | ||
66 | for(i=0;i<32;i++) | ||
67 | sm[mlen+32+i] = s[i]; | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | int crypto_sign_open( | ||
73 | unsigned char *m,unsigned long long *mlen, | ||
74 | const unsigned char *sm,unsigned long long smlen, | ||
75 | const unsigned char *pk | ||
76 | ) | ||
77 | { | ||
78 | int i; | ||
79 | unsigned char t1[32], t2[32]; | ||
80 | ge25519 get1, get2, gepk; | ||
81 | sc25519 schmr, scs; | ||
82 | unsigned char hmr[crypto_hash_sha512_BYTES]; | ||
83 | |||
84 | if (ge25519_unpack_vartime(&get1, sm)) return -1; | ||
85 | if (ge25519_unpack_vartime(&gepk, pk)) return -1; | ||
86 | |||
87 | crypto_hash_sha512(hmr,sm,smlen-32); | ||
88 | |||
89 | sc25519_from64bytes(&schmr, hmr); | ||
90 | ge25519_scalarmult(&get1, &get1, &schmr); | ||
91 | ge25519_add(&get1, &get1, &gepk); | ||
92 | ge25519_pack(t1, &get1); | ||
93 | |||
94 | sc25519_from32bytes(&scs, &sm[smlen-32]); | ||
95 | ge25519_scalarmult_base(&get2, &scs); | ||
96 | ge25519_pack(t2, &get2); | ||
97 | |||
98 | for(i=0;i<smlen-64;i++) | ||
99 | m[i] = sm[i + 32]; | ||
100 | *mlen = smlen-64; | ||
101 | |||
102 | return crypto_verify_32(t1, t2); | ||
103 | } | ||