aboutsummaryrefslogtreecommitdiff
path: root/src/util/tweetnacl-gnunet.c
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2020-05-06 18:39:16 +0530
committerFlorian Dold <florian.dold@gmail.com>2020-05-06 18:46:52 +0530
commitd7028a584bf96fb5b84c765a885159cabb95dea2 (patch)
tree681728f41a12075f847e30d4bc5c0cae418f24b7 /src/util/tweetnacl-gnunet.c
parent35698918f80cb0b10c21fa450bf265564faf981a (diff)
downloadgnunet-d7028a584bf96fb5b84c765a885159cabb95dea2.tar.gz
gnunet-d7028a584bf96fb5b84c765a885159cabb95dea2.zip
move from tweetnacl (+custom hacks) -> only sodium
Diffstat (limited to 'src/util/tweetnacl-gnunet.c')
-rw-r--r--src/util/tweetnacl-gnunet.c560
1 files changed, 0 insertions, 560 deletions
diff --git a/src/util/tweetnacl-gnunet.c b/src/util/tweetnacl-gnunet.c
deleted file mode 100644
index f01667adb..000000000
--- a/src/util/tweetnacl-gnunet.c
+++ /dev/null
@@ -1,560 +0,0 @@
1/*
2 This file has been placed in the public domain.
3
4 Based on TweetNaCl version 20140427
5
6 Originally obtained from:
7 https://tweetnacl.cr.yp.to/20140427/tweetnacl.h
8
9 SPDX-License-Identifier: 0BSD
10*/
11
12#include "platform.h"
13#include "gnunet_crypto_lib.h"
14#include "tweetnacl-gnunet.h"
15#define FOR(i,n) for (i = 0; i < n; ++i)
16
17typedef uint8_t u8;
18typedef uint32_t u32;
19typedef uint64_t u64;
20typedef int64_t i64;
21typedef i64 gf[16];
22
23static const u8 _9[32] = {9};
24static const gf
25 gf0,
26 gf1 = {1},
27 _121665 = {0xDB41,1},
28 D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898,
29 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
30 D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130,
31 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
32 X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c,
33 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
34 Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666,
35 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
36 I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7,
37 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
38
39static int
40vn (const u8 *x,const u8 *y,int n)
41{
42 u32 i,d = 0;
43 FOR (i,n) d |= x[i] ^ y[i];
44 return (1 & ((d - 1) >> 8)) - 1;
45}
46
47static int
48crypto_verify_32 (const u8 *x,const u8 *y)
49{
50 return vn (x,y,32);
51}
52
53static void
54set25519 (gf r, const gf a)
55{
56 int i;
57 FOR (i,16) r[i] = a[i];
58}
59
60static void
61car25519 (gf o)
62{
63 int i;
64 i64 c;
65 FOR (i,16) {
66 o[i] += (1LL << 16);
67 c = o[i] >> 16;
68 o[(i + 1) * (i<15)] += c - 1 + 37 * (c - 1) * (i==15);
69 o[i] -= c << 16;
70 }
71}
72
73static void
74sel25519 (gf p,gf q,int b)
75{
76 i64 t,i,c = ~(b - 1);
77 FOR (i,16) {
78 t = c & (p[i] ^ q[i]);
79 p[i] ^= t;
80 q[i] ^= t;
81 }
82}
83
84static void
85pack25519 (u8 *o,const gf n)
86{
87 int i,j,b;
88 gf m,t;
89 FOR (i,16) t[i] = n[i];
90 car25519 (t);
91 car25519 (t);
92 car25519 (t);
93 FOR (j,2) {
94 m[0] = t[0] - 0xffed;
95 for (i = 1; i<15; i++) {
96 m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
97 m[i - 1] &= 0xffff;
98 }
99 m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
100 b = (m[15] >> 16) & 1;
101 m[14] &= 0xffff;
102 sel25519 (t,m,1 - b);
103 }
104 FOR (i,16) {
105 o[2 * i] = t[i] & 0xff;
106 o[2 * i + 1] = t[i] >> 8;
107 }
108}
109
110static int
111neq25519 (const gf a, const gf b)
112{
113 u8 c[32],d[32];
114 pack25519 (c,a);
115 pack25519 (d,b);
116 return crypto_verify_32 (c,d);
117}
118
119static uint8_t
120par25519 (const gf a)
121{
122 u8 d[32];
123 pack25519 (d,a);
124 return d[0] & 1;
125}
126
127static void
128unpack25519 (gf o, const u8 *n)
129{
130 int i;
131 FOR (i,16) o[i] = n[2 * i] + ((i64) n[2 * i + 1] << 8);
132 o[15] &= 0x7fff;
133}
134
135static void
136A (gf o,const gf a,const gf b)
137{
138 int i;
139 FOR (i,16) o[i] = a[i] + b[i];
140}
141
142static void
143Z (gf o,const gf a,const gf b)
144{
145 int i;
146 FOR (i,16) o[i] = a[i] - b[i];
147}
148
149static void
150M (gf o,const gf a,const gf b)
151{
152 i64 i,j,t[31];
153 FOR (i,31) t[i] = 0;
154 FOR (i,16) FOR (j,16) t[i + j] += a[i] * b[j];
155 FOR (i,15) t[i] += 38 * t[i + 16];
156 FOR (i,16) o[i] = t[i];
157 car25519 (o);
158 car25519 (o);
159}
160
161static void
162S (gf o,const gf a)
163{
164 M (o,a,a);
165}
166
167static void
168inv25519 (gf o,const gf i)
169{
170 gf c;
171 int a;
172 FOR (a,16) c[a] = i[a];
173 for (a = 253; a>=0; a--) {
174 S (c,c);
175 if ((a!=2)&&(a!=4))
176 M (c,c,i);
177 }
178 FOR (a,16) o[a] = c[a];
179}
180
181static void pow2523 (gf o,const gf i)
182{
183 gf c;
184 int a;
185 FOR (a,16) c[a] = i[a];
186 for (a = 250; a>=0; a--) {
187 S (c,c);
188 if (a!=1)
189 M (c,c,i);
190 }
191 FOR (a,16) o[a] = c[a];
192}
193
194int
195GNUNET_TWEETNACL_scalarmult_curve25519 (u8 *q,const u8 *n,const u8 *p)
196{
197 u8 z[32];
198 i64 x[80],r,i;
199 gf a,b,c,d,e,f;
200 FOR (i,31) z[i] = n[i];
201 z[31] = (n[31] & 127) | 64;
202 z[0] &= 248;
203 unpack25519 (x,p);
204 FOR (i,16) {
205 b[i] = x[i];
206 d[i] = a[i] = c[i] = 0;
207 }
208 a[0] = d[0] = 1;
209 for (i = 254; i>=0; --i) {
210 r = (z[i >> 3] >> (i & 7)) & 1;
211 sel25519 (a,b,r);
212 sel25519 (c,d,r);
213 A (e,a,c);
214 Z (a,a,c);
215 A (c,b,d);
216 Z (b,b,d);
217 S (d,e);
218 S (f,a);
219 M (a,c,a);
220 M (c,b,e);
221 A (e,a,c);
222 Z (a,a,c);
223 S (b,a);
224 Z (c,d,f);
225 M (a,c,_121665);
226 A (a,a,d);
227 M (c,c,a);
228 M (a,d,f);
229 M (d,b,x);
230 S (b,e);
231 sel25519 (a,b,r);
232 sel25519 (c,d,r);
233 }
234 FOR (i,16) {
235 x[i + 16] = a[i];
236 x[i + 32] = c[i];
237 x[i + 48] = b[i];
238 x[i + 64] = d[i];
239 }
240 inv25519 (x + 32,x + 32);
241 M (x + 16,x + 16,x + 32);
242 pack25519 (q,x + 16);
243 return 0;
244}
245
246int
247GNUNET_TWEETNACL_scalarmult_curve25519_base (u8 *q,const u8 *n)
248{
249 return GNUNET_TWEETNACL_scalarmult_curve25519 (q,n,_9);
250}
251
252static int
253crypto_hash (u8 *out,const u8 *m,u64 n)
254{
255 struct GNUNET_HashCode *hc = (void *) out;
256 GNUNET_CRYPTO_hash (m, n, hc);
257 return 0;
258}
259
260static void
261add (gf p[4],gf q[4])
262{
263 gf a,b,c,d,t,e,f,g,h;
264
265 Z (a, p[1], p[0]);
266 Z (t, q[1], q[0]);
267 M (a, a, t);
268 A (b, p[0], p[1]);
269 A (t, q[0], q[1]);
270 M (b, b, t);
271 M (c, p[3], q[3]);
272 M (c, c, D2);
273 M (d, p[2], q[2]);
274 A (d, d, d);
275 Z (e, b, a);
276 Z (f, d, c);
277 A (g, d, c);
278 A (h, b, a);
279
280 M (p[0], e, f);
281 M (p[1], h, g);
282 M (p[2], g, f);
283 M (p[3], e, h);
284}
285
286static void
287cswap (gf p[4],gf q[4],u8 b)
288{
289 int i;
290 FOR (i,4)
291 sel25519 (p[i],q[i],b);
292}
293
294static void
295pack (u8 *r,gf p[4])
296{
297 gf tx, ty, zi;
298 inv25519 (zi, p[2]);
299 M (tx, p[0], zi);
300 M (ty, p[1], zi);
301 pack25519 (r, ty);
302 r[31] ^= par25519 (tx) << 7;
303}
304
305static void
306scalarmult (gf p[4],gf q[4],const u8 *s)
307{
308 int i;
309 set25519 (p[0],gf0);
310 set25519 (p[1],gf1);
311 set25519 (p[2],gf1);
312 set25519 (p[3],gf0);
313 for (i = 255; i >= 0; --i) {
314 u8 b = (s[i / 8] >> (i & 7)) & 1;
315 cswap (p,q,b);
316 add (q,p);
317 add (p,p);
318 cswap (p,q,b);
319 }
320}
321
322static void
323scalarbase (gf p[4],const u8 *s)
324{
325 gf q[4];
326 set25519 (q[0],X);
327 set25519 (q[1],Y);
328 set25519 (q[2],gf1);
329 M (q[3],X,Y);
330 scalarmult (p,q,s);
331}
332
333static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6,
334 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0,
335 0, 0, 0, 0, 0, 0, 0, 0,
336 0, 0, 0, 0x10};
337
338static void
339modL (u8 *r,i64 x[64])
340{
341 i64 carry,i,j;
342 for (i = 63; i >= 32; --i) {
343 carry = 0;
344 for (j = i - 32; j < i - 12; ++j) {
345 x[j] += carry - 16 * x[i] * L[j - (i - 32)];
346 carry = (x[j] + 128) >> 8;
347 x[j] -= carry << 8;
348 }
349 x[j] += carry;
350 x[i] = 0;
351 }
352 carry = 0;
353 FOR (j,32) {
354 x[j] += carry - (x[31] >> 4) * L[j];
355 carry = x[j] >> 8;
356 x[j] &= 255;
357 }
358 FOR (j,32) x[j] -= carry * L[j];
359 FOR (i,32) {
360 x[i + 1] += x[i] >> 8;
361 r[i] = x[i] & 255;
362 }
363}
364
365static void
366reduce (u8 *r)
367{
368 i64 x[64],i;
369 FOR (i,64) x[i] = (u64) r[i];
370 FOR (i,64) r[i] = 0;
371 modL (r,x);
372}
373
374static int
375unpackneg (gf r[4],const u8 p[32])
376{
377 gf t, chk, num, den, den2, den4, den6;
378 set25519 (r[2],gf1);
379 unpack25519 (r[1],p);
380 S (num,r[1]);
381 M (den,num,D);
382 Z (num,num,r[2]);
383 A (den,r[2],den);
384
385 S (den2,den);
386 S (den4,den2);
387 M (den6,den4,den2);
388 M (t,den6,num);
389 M (t,t,den);
390
391 pow2523 (t,t);
392 M (t,t,num);
393 M (t,t,den);
394 M (t,t,den);
395 M (r[0],t,den);
396
397 S (chk,r[0]);
398 M (chk,chk,den);
399 if (neq25519 (chk, num))
400 M (r[0],r[0],I);
401
402 S (chk,r[0]);
403 M (chk,chk,den);
404 if (neq25519 (chk, num))
405 return -1;
406
407 if (par25519 (r[0]) == (p[31] >> 7))
408 Z (r[0],gf0,r[0]);
409
410 M (r[3],r[0],r[1]);
411 return 0;
412}
413
414/* The following functions have been added for GNUnet */
415
416void
417GNUNET_TWEETNACL_sign_pk_from_seed (u8 *pk, const u8 *seed)
418{
419 u8 d[64];
420 gf p[4];
421
422 crypto_hash (d, seed, 32);
423 d[0] &= 248;
424 d[31] &= 127;
425 d[31] |= 64;
426
427 scalarbase (p, d);
428 pack (pk, p);
429}
430
431void
432GNUNET_TWEETNACL_scalarmult_gnunet_ecdsa (u8 *pk, const u8 *s)
433{
434 u8 d[64];
435 gf p[4];
436
437 // Treat s as little endian.
438 for (u32 i = 0; i < 32; i++)
439 d[i] = s[31 - i];
440
441 // For GNUnet, we don't normalize d
442
443 scalarbase (p, d);
444 pack (pk, p);
445}
446
447void
448GNUNET_TWEETNACL_sign_sk_from_seed (u8 *sk, const u8 *seed)
449{
450 u8 d[64];
451 gf p[4];
452 u8 pk[32];
453 int i;
454
455 crypto_hash (d, seed, 32);
456 d[0] &= 248;
457 d[31] &= 127;
458 d[31] |= 64;
459
460 scalarbase (p,d);
461 pack (pk,p);
462
463 FOR (i,32) sk[i] = seed[i];
464 FOR (i,32) sk[32 + i] = pk[i];
465}
466
467int
468GNUNET_TWEETNACL_sign_ed25519_pk_to_curve25519 (u8 *x25519_pk,
469 const u8 *ed25519_pk)
470{
471 gf ge_a[4];
472 gf x;
473 gf one_minus_y;
474
475 if (0 != unpackneg (ge_a, ed25519_pk))
476 return -1;
477
478 set25519 (one_minus_y, gf1);
479 Z (one_minus_y, one_minus_y, ge_a[1]);
480
481 set25519 (x, gf1);
482 A (x, x, ge_a[1]);
483
484 inv25519 (one_minus_y, one_minus_y);
485 M (x, x, one_minus_y);
486 pack25519 (x25519_pk, x);
487
488 return 0;
489}
490
491int GNUNET_TWEETNACL_sign_detached_verify (const u8 *sig,
492 const u8 *m,
493 u64 n,
494 const u8 *pk)
495{
496 struct GNUNET_HashContext *hc;
497 u8 t[32],h[64];
498 gf p[4],q[4];
499
500 if (unpackneg (q,pk))
501 return -1;
502
503 hc = GNUNET_CRYPTO_hash_context_start ();
504 GNUNET_CRYPTO_hash_context_read (hc, sig, 32);
505 GNUNET_CRYPTO_hash_context_read (hc, pk, 32);
506 GNUNET_CRYPTO_hash_context_read (hc, m, n);
507 GNUNET_CRYPTO_hash_context_finish (hc, (void *) h);
508
509 reduce (h);
510 scalarmult (p,q,h);
511
512 scalarbase (q,sig+32);
513 add (p,q);
514 pack (t,p);
515
516 if (crypto_verify_32 (sig, t))
517 return -1;
518 return 0;
519}
520
521int
522GNUNET_TWEETNACL_sign_detached (u8 *sig,
523 const u8 *m,
524 u64 n,
525 const u8 *sk)
526{
527 struct GNUNET_HashContext *hc;
528 u8 d[64],h[64],r[64];
529 i64 i,j,x[64];
530 gf p[4];
531
532 crypto_hash (d, sk, 32);
533 d[0] &= 248;
534 d[31] &= 127;
535 d[31] |= 64;
536
537 hc = GNUNET_CRYPTO_hash_context_start ();
538 GNUNET_CRYPTO_hash_context_read (hc, d + 32, 32);
539 GNUNET_CRYPTO_hash_context_read (hc, m, n);
540 GNUNET_CRYPTO_hash_context_finish (hc, (void *) r);
541
542 reduce (r);
543 scalarbase (p,r);
544 pack (sig,p);
545
546 hc = GNUNET_CRYPTO_hash_context_start ();
547 GNUNET_CRYPTO_hash_context_read (hc, sig, 32);
548 GNUNET_CRYPTO_hash_context_read (hc, sk + 32, 32);
549 GNUNET_CRYPTO_hash_context_read (hc, m, n);
550 GNUNET_CRYPTO_hash_context_finish (hc, (void *) h);
551
552 reduce (h);
553
554 FOR (i,64) x[i] = 0;
555 FOR (i,32) x[i] = (u64) r[i];
556 FOR (i,32) FOR (j,32) x[i + j] += h[i] * (u64) d[j];
557 modL (sig + 32,x);
558
559 return 0;
560}