aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/util/Makefile.am1
-rw-r--r--src/util/crypto_ecc.c109
-rw-r--r--src/util/tweetnacl-gnunet.c530
-rw-r--r--src/util/tweetnacl-gnunet.h85
4 files changed, 724 insertions, 1 deletions
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index b89250711..fce064d0c 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -93,6 +93,7 @@ libgnunetutil_la_SOURCES = \
93 strings.c \ 93 strings.c \
94 time.c \ 94 time.c \
95 tun.c \ 95 tun.c \
96 tweetnacl-gnunet.c \
96 speedup.c speedup.h \ 97 speedup.c speedup.h \
97 proc_compat.c 98 proc_compat.c
98 99
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index 12284a7a9..86beb9109 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -22,15 +22,20 @@
22 * @file util/crypto_ecc.c 22 * @file util/crypto_ecc.c
23 * @brief public key cryptography (ECC) with libgcrypt 23 * @brief public key cryptography (ECC) with libgcrypt
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 * @author Florian Dold
25 */ 26 */
26#include "platform.h" 27#include "platform.h"
27#include <gcrypt.h> 28#include <gcrypt.h>
28#include "gnunet_crypto_lib.h" 29#include "gnunet_crypto_lib.h"
29#include "gnunet_strings_lib.h" 30#include "gnunet_strings_lib.h"
30#include "benchmark.h" 31#include "benchmark.h"
32#include "tweetnacl-gnunet.h"
31 33
32#define EXTRA_CHECKS 0 34#define EXTRA_CHECKS 0
33 35
36#define NEW_CRYPTO 0
37
38
34/** 39/**
35 * Name of the curve we are using. Note that we have hard-coded 40 * Name of the curve we are using. Note that we have hard-coded
36 * structs that use 256 bits, so using a bigger curve will require 41 * structs that use 256 bits, so using a bigger curve will require
@@ -159,6 +164,7 @@ decode_private_ecdsa_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
159} 164}
160 165
161 166
167#if !NEW_CRYPTO
162/** 168/**
163 * Convert the given private key from the network format to the 169 * Convert the given private key from the network format to the
164 * S-expression that can be used by libgcrypt. 170 * S-expression that can be used by libgcrypt.
@@ -192,8 +198,10 @@ decode_private_eddsa_key (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
192#endif 198#endif
193 return result; 199 return result;
194} 200}
201#endif /* !NEW_CRYPTO */
195 202
196 203
204#if !NEW_CRYPTO
197/** 205/**
198 * Convert the given private key from the network format to the 206 * Convert the given private key from the network format to the
199 * S-expression that can be used by libgcrypt. 207 * S-expression that can be used by libgcrypt.
@@ -227,6 +235,7 @@ decode_private_ecdhe_key (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv)
227#endif 235#endif
228 return result; 236 return result;
229} 237}
238#endif /* !NEW_CRYPTO */
230 239
231 240
232/** 241/**
@@ -271,6 +280,11 @@ GNUNET_CRYPTO_eddsa_key_get_public (
271 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, 280 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
272 struct GNUNET_CRYPTO_EddsaPublicKey *pub) 281 struct GNUNET_CRYPTO_EddsaPublicKey *pub)
273{ 282{
283#if NEW_CRYPTO
284 BENCHMARK_START (eddsa_key_get_public);
285 crypto_sign_pk_from_seed (pub->q_y, priv->d);
286 BENCHMARK_END (eddsa_key_get_public);
287#else
274 gcry_sexp_t sexp; 288 gcry_sexp_t sexp;
275 gcry_ctx_t ctx; 289 gcry_ctx_t ctx;
276 gcry_mpi_t q; 290 gcry_mpi_t q;
@@ -288,6 +302,7 @@ GNUNET_CRYPTO_eddsa_key_get_public (
288 gcry_ctx_release (ctx); 302 gcry_ctx_release (ctx);
289 303
290 BENCHMARK_END (eddsa_key_get_public); 304 BENCHMARK_END (eddsa_key_get_public);
305#endif
291} 306}
292 307
293 308
@@ -302,6 +317,11 @@ GNUNET_CRYPTO_ecdhe_key_get_public (
302 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, 317 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
303 struct GNUNET_CRYPTO_EcdhePublicKey *pub) 318 struct GNUNET_CRYPTO_EcdhePublicKey *pub)
304{ 319{
320#if NEW_CRYPTO
321 BENCHMARK_START (ecdhe_key_get_public);
322 crypto_scalarmult_curve25519_base (pub->q_y, priv->d);
323 BENCHMARK_END (ecdhe_key_get_public);
324#else
305 gcry_sexp_t sexp; 325 gcry_sexp_t sexp;
306 gcry_ctx_t ctx; 326 gcry_ctx_t ctx;
307 gcry_mpi_t q; 327 gcry_mpi_t q;
@@ -319,6 +339,7 @@ GNUNET_CRYPTO_ecdhe_key_get_public (
319 gcry_ctx_release (ctx); 339 gcry_ctx_release (ctx);
320 340
321 BENCHMARK_END (ecdhe_key_get_public); 341 BENCHMARK_END (ecdhe_key_get_public);
342#endif
322} 343}
323 344
324 345
@@ -629,6 +650,14 @@ GNUNET_CRYPTO_ecdhe_key_create ()
629int 650int
630GNUNET_CRYPTO_ecdhe_key_create2 (struct GNUNET_CRYPTO_EcdhePrivateKey *pk) 651GNUNET_CRYPTO_ecdhe_key_create2 (struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
631{ 652{
653#if NEW_CRYPTO
654 BENCHMARK_START (ecdhe_key_create);
655 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
656 pk,
657 sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
658 BENCHMARK_END (ecdhe_key_create);
659 return GNUNET_OK;
660#else
632 gcry_sexp_t priv_sexp; 661 gcry_sexp_t priv_sexp;
633 gcry_sexp_t s_keyparam; 662 gcry_sexp_t s_keyparam;
634 gcry_mpi_t d; 663 gcry_mpi_t d;
@@ -676,6 +705,7 @@ GNUNET_CRYPTO_ecdhe_key_create2 (struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
676 BENCHMARK_END (ecdhe_key_create); 705 BENCHMARK_END (ecdhe_key_create);
677 706
678 return GNUNET_OK; 707 return GNUNET_OK;
708#endif
679} 709}
680 710
681 711
@@ -743,6 +773,18 @@ GNUNET_CRYPTO_ecdsa_key_create ()
743struct GNUNET_CRYPTO_EddsaPrivateKey * 773struct GNUNET_CRYPTO_EddsaPrivateKey *
744GNUNET_CRYPTO_eddsa_key_create () 774GNUNET_CRYPTO_eddsa_key_create ()
745{ 775{
776#if NEW_CRYPTO
777 struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
778
779 BENCHMARK_START (eddsa_key_create);
780 priv = GNUNET_new (struct GNUNET_CRYPTO_EddsaPrivateKey);
781 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
782 priv,
783 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
784 BENCHMARK_END (eddsa_key_create);
785
786 return priv;
787#else
746 struct GNUNET_CRYPTO_EddsaPrivateKey *priv; 788 struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
747 gcry_sexp_t priv_sexp; 789 gcry_sexp_t priv_sexp;
748 gcry_sexp_t s_keyparam; 790 gcry_sexp_t s_keyparam;
@@ -752,7 +794,7 @@ GNUNET_CRYPTO_eddsa_key_create ()
752 BENCHMARK_START (eddsa_key_create); 794 BENCHMARK_START (eddsa_key_create);
753 795
754#if CRYPTO_BUG 796#if CRYPTO_BUG
755again: 797 again:
756#endif 798#endif
757 if (0 != (rc = gcry_sexp_build (&s_keyparam, 799 if (0 != (rc = gcry_sexp_build (&s_keyparam,
758 NULL, 800 NULL,
@@ -800,6 +842,7 @@ again:
800 BENCHMARK_END (eddsa_key_create); 842 BENCHMARK_END (eddsa_key_create);
801 843
802 return priv; 844 return priv;
845#endif
803} 846}
804 847
805 848
@@ -828,6 +871,7 @@ GNUNET_CRYPTO_ecdsa_key_get_anonymous ()
828} 871}
829 872
830 873
874#if !NEW_CRYPTO
831/** 875/**
832 * Convert the data specified in the given purpose argument to an 876 * Convert the data specified in the given purpose argument to an
833 * S-expression suitable for signature operations. 877 * S-expression suitable for signature operations.
@@ -870,6 +914,7 @@ data_to_eddsa_value (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
870#endif 914#endif
871 return data; 915 return data;
872} 916}
917#endif /* !NEW_CRYPTO */
873 918
874 919
875/** 920/**
@@ -988,6 +1033,22 @@ GNUNET_CRYPTO_eddsa_sign (
988 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, 1033 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
989 struct GNUNET_CRYPTO_EddsaSignature *sig) 1034 struct GNUNET_CRYPTO_EddsaSignature *sig)
990{ 1035{
1036
1037#if NEW_CRYPTO
1038 size_t mlen = ntohl (purpose->size);
1039 unsigned char sk[crypto_sign_SECRETKEYBYTES];
1040 int res;
1041
1042 BENCHMARK_START (eddsa_sign);
1043 crypto_sign_sk_from_seed (sk, priv->d);
1044 res = crypto_sign_detached ((uint8_t *) sig,
1045 (uint8_t *) purpose,
1046 mlen,
1047 sk);
1048 BENCHMARK_END (eddsa_sign);
1049 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
1050#else
1051
991 gcry_sexp_t priv_sexp; 1052 gcry_sexp_t priv_sexp;
992 gcry_sexp_t sig_sexp; 1053 gcry_sexp_t sig_sexp;
993 gcry_sexp_t data; 1054 gcry_sexp_t data;
@@ -1029,6 +1090,7 @@ GNUNET_CRYPTO_eddsa_sign (
1029 BENCHMARK_END (eddsa_sign); 1090 BENCHMARK_END (eddsa_sign);
1030 1091
1031 return GNUNET_OK; 1092 return GNUNET_OK;
1093#endif
1032} 1094}
1033 1095
1034 1096
@@ -1116,6 +1178,21 @@ GNUNET_CRYPTO_eddsa_verify (
1116 const struct GNUNET_CRYPTO_EddsaSignature *sig, 1178 const struct GNUNET_CRYPTO_EddsaSignature *sig,
1117 const struct GNUNET_CRYPTO_EddsaPublicKey *pub) 1179 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
1118{ 1180{
1181#if NEW_CRYPTO
1182 unsigned char *m = (void *) validate;
1183 size_t mlen = ntohl (validate->size);
1184 unsigned char *s = (void *) sig;
1185
1186 int res;
1187
1188 if (purpose != ntohl (validate->purpose))
1189 return GNUNET_SYSERR; /* purpose mismatch */
1190
1191 BENCHMARK_START (eddsa_verify);
1192 res = crypto_sign_detached_verify (s, m, mlen, pub->q_y);
1193 BENCHMARK_END (eddsa_verify);
1194 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
1195#else
1119 gcry_sexp_t data; 1196 gcry_sexp_t data;
1120 gcry_sexp_t sig_sexpr; 1197 gcry_sexp_t sig_sexpr;
1121 gcry_sexp_t pub_sexpr; 1198 gcry_sexp_t pub_sexpr;
@@ -1167,6 +1244,7 @@ GNUNET_CRYPTO_eddsa_verify (
1167 } 1244 }
1168 BENCHMARK_END (eddsa_verify); 1245 BENCHMARK_END (eddsa_verify);
1169 return GNUNET_OK; 1246 return GNUNET_OK;
1247#endif
1170} 1248}
1171 1249
1172 1250
@@ -1183,6 +1261,12 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1183 const struct GNUNET_CRYPTO_EcdhePublicKey *pub, 1261 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1184 struct GNUNET_HashCode *key_material) 1262 struct GNUNET_HashCode *key_material)
1185{ 1263{
1264#if NEW_CRYPTO
1265 uint8_t p[crypto_scalarmult_BYTES];
1266 crypto_scalarmult_curve25519 (p, priv->d, pub->q_y);
1267 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
1268 return GNUNET_OK;
1269#else
1186 gcry_mpi_point_t result; 1270 gcry_mpi_point_t result;
1187 gcry_mpi_point_t q; 1271 gcry_mpi_point_t q;
1188 gcry_mpi_t d; 1272 gcry_mpi_t d;
@@ -1238,6 +1322,7 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1238 gcry_mpi_release (result_x); 1322 gcry_mpi_release (result_x);
1239 BENCHMARK_END (ecc_ecdh); 1323 BENCHMARK_END (ecc_ecdh);
1240 return GNUNET_OK; 1324 return GNUNET_OK;
1325#endif
1241} 1326}
1242 1327
1243 1328
@@ -1384,6 +1469,7 @@ GNUNET_CRYPTO_ecdsa_public_key_derive (
1384} 1469}
1385 1470
1386 1471
1472#if !NEW_CRYPTO
1387/** 1473/**
1388 * Reverse the sequence of the bytes in @a buffer 1474 * Reverse the sequence of the bytes in @a buffer
1389 * 1475 *
@@ -1447,6 +1533,7 @@ eddsa_d_to_a (gcry_mpi_t d)
1447 GNUNET_CRYPTO_mpi_scan_unsigned (&a, digest, 32); 1533 GNUNET_CRYPTO_mpi_scan_unsigned (&a, digest, 32);
1448 return a; 1534 return a;
1449} 1535}
1536#endif
1450 1537
1451 1538
1452/** 1539/**
@@ -1503,6 +1590,16 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1503 const struct GNUNET_CRYPTO_EcdhePublicKey *pub, 1590 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1504 struct GNUNET_HashCode *key_material) 1591 struct GNUNET_HashCode *key_material)
1505{ 1592{
1593#if NEW_CRYPTO
1594 struct GNUNET_HashCode hc;
1595 uint8_t a[crypto_scalarmult_BYTES];
1596 uint8_t p[crypto_scalarmult_BYTES];
1597 GNUNET_CRYPTO_hash (priv, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), &hc);
1598 memcpy (a, &hc, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
1599 crypto_scalarmult_curve25519 (p, a, pub->q_y);
1600 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
1601 return GNUNET_OK;
1602#else
1506 gcry_mpi_point_t result; 1603 gcry_mpi_point_t result;
1507 gcry_mpi_point_t q; 1604 gcry_mpi_point_t q;
1508 gcry_mpi_t d; 1605 gcry_mpi_t d;
@@ -1542,6 +1639,7 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1542 gcry_ctx_release (ctx); 1639 gcry_ctx_release (ctx);
1543 BENCHMARK_END (eddsa_ecdh); 1640 BENCHMARK_END (eddsa_ecdh);
1544 return ret; 1641 return ret;
1642#endif
1545} 1643}
1546 1644
1547 1645
@@ -1613,6 +1711,14 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1613 const struct GNUNET_CRYPTO_EddsaPublicKey *pub, 1711 const struct GNUNET_CRYPTO_EddsaPublicKey *pub,
1614 struct GNUNET_HashCode *key_material) 1712 struct GNUNET_HashCode *key_material)
1615{ 1713{
1714#if NEW_CRYPTO
1715 uint8_t p[crypto_scalarmult_BYTES];
1716 uint8_t curve25510_pk[crypto_sign_PUBLICKEYBYTES];
1717 crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y);
1718 crypto_scalarmult_curve25519 (p, priv->d, curve25510_pk);
1719 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
1720 return GNUNET_OK;
1721#else
1616 gcry_mpi_point_t result; 1722 gcry_mpi_point_t result;
1617 gcry_mpi_point_t q; 1723 gcry_mpi_point_t q;
1618 gcry_mpi_t d; 1724 gcry_mpi_t d;
@@ -1648,6 +1754,7 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1648 gcry_ctx_release (ctx); 1754 gcry_ctx_release (ctx);
1649 BENCHMARK_END (ecdh_eddsa); 1755 BENCHMARK_END (ecdh_eddsa);
1650 return ret; 1756 return ret;
1757#endif
1651} 1758}
1652 1759
1653 1760
diff --git a/src/util/tweetnacl-gnunet.c b/src/util/tweetnacl-gnunet.c
new file mode 100644
index 000000000..b0d87c2fe
--- /dev/null
+++ b/src/util/tweetnacl-gnunet.c
@@ -0,0 +1,530 @@
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
10#include "platform.h"
11#include "gnunet_crypto_lib.h"
12#include "tweetnacl-gnunet.h"
13#define FOR(i,n) for (i = 0; i < n; ++i)
14#define sv static void
15
16typedef uint8_t u8;
17typedef uint32_t u32;
18typedef uint64_t u64;
19typedef int64_t i64;
20typedef i64 gf[16];
21
22static void randombytes (u8 *data,u64 len)
23{
24 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, data, len);
25}
26
27static const u8 _9[32] = {9};
28static const gf
29 gf0,
30 gf1 = {1},
31 _121665 = {0xDB41,1},
32 D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898,
33 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
34 D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130,
35 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
36 X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c,
37 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
38 Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666,
39 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
40 I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7,
41 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
42
43static int vn (const u8 *x,const u8 *y,int n)
44{
45 u32 i,d = 0;
46 FOR (i,n) d |= x[i] ^ y[i];
47 return (1 & ((d - 1) >> 8)) - 1;
48}
49
50int crypto_verify_16 (const u8 *x,const u8 *y)
51{
52 return vn (x,y,16);
53}
54
55int crypto_verify_32 (const u8 *x,const u8 *y)
56{
57 return vn (x,y,32);
58}
59
60sv set25519 (gf r, const gf a)
61{
62 int i;
63 FOR (i,16) r[i] = a[i];
64}
65
66sv car25519 (gf o)
67{
68 int i;
69 i64 c;
70 FOR (i,16) {
71 o[i] += (1LL << 16);
72 c = o[i] >> 16;
73 o[(i + 1) * (i<15)] += c - 1 + 37 * (c - 1) * (i==15);
74 o[i] -= c << 16;
75 }
76}
77
78sv sel25519 (gf p,gf q,int b)
79{
80 i64 t,i,c = ~(b - 1);
81 FOR (i,16) {
82 t = c & (p[i] ^ q[i]);
83 p[i] ^= t;
84 q[i] ^= t;
85 }
86}
87
88sv pack25519 (u8 *o,const gf n)
89{
90 int i,j,b;
91 gf m,t;
92 FOR (i,16) t[i] = n[i];
93 car25519 (t);
94 car25519 (t);
95 car25519 (t);
96 FOR (j,2) {
97 m[0] = t[0] - 0xffed;
98 for (i = 1; i<15; i++) {
99 m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
100 m[i - 1] &= 0xffff;
101 }
102 m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
103 b = (m[15] >> 16) & 1;
104 m[14] &= 0xffff;
105 sel25519 (t,m,1 - b);
106 }
107 FOR (i,16) {
108 o[2 * i] = t[i] & 0xff;
109 o[2 * i + 1] = t[i] >> 8;
110 }
111}
112
113static int neq25519 (const gf a, const gf b)
114{
115 u8 c[32],d[32];
116 pack25519 (c,a);
117 pack25519 (d,b);
118 return crypto_verify_32 (c,d);
119}
120
121static u8 par25519 (const gf a)
122{
123 u8 d[32];
124 pack25519 (d,a);
125 return d[0] & 1;
126}
127
128sv unpack25519 (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
135sv A (gf o,const gf a,const gf b)
136{
137 int i;
138 FOR (i,16) o[i] = a[i] + b[i];
139}
140
141sv Z (gf o,const gf a,const gf b)
142{
143 int i;
144 FOR (i,16) o[i] = a[i] - b[i];
145}
146
147sv M (gf o,const gf a,const gf b)
148{
149 i64 i,j,t[31];
150 FOR (i,31) t[i] = 0;
151 FOR (i,16) FOR (j,16) t[i + j] += a[i] * b[j];
152 FOR (i,15) t[i] += 38 * t[i + 16];
153 FOR (i,16) o[i] = t[i];
154 car25519 (o);
155 car25519 (o);
156}
157
158sv S (gf o,const gf a)
159{
160 M (o,a,a);
161}
162
163sv inv25519 (gf o,const gf i)
164{
165 gf c;
166 int a;
167 FOR (a,16) c[a] = i[a];
168 for (a = 253; a>=0; a--) {
169 S (c,c);
170 if ((a!=2)&&(a!=4))
171 M (c,c,i);
172 }
173 FOR (a,16) o[a] = c[a];
174}
175
176sv pow2523 (gf o,const gf i)
177{
178 gf c;
179 int a;
180 FOR (a,16) c[a] = i[a];
181 for (a = 250; a>=0; a--) {
182 S (c,c);
183 if (a!=1)
184 M (c,c,i);
185 }
186 FOR (a,16) o[a] = c[a];
187}
188
189int crypto_scalarmult (u8 *q,const u8 *n,const u8 *p)
190{
191 u8 z[32];
192 i64 x[80],r,i;
193 gf a,b,c,d,e,f;
194 FOR (i,31) z[i] = n[i];
195 z[31] = (n[31] & 127) | 64;
196 z[0] &= 248;
197 unpack25519 (x,p);
198 FOR (i,16) {
199 b[i] = x[i];
200 d[i] = a[i] = c[i] = 0;
201 }
202 a[0] = d[0] = 1;
203 for (i = 254; i>=0; --i) {
204 r = (z[i >> 3] >> (i & 7)) & 1;
205 sel25519 (a,b,r);
206 sel25519 (c,d,r);
207 A (e,a,c);
208 Z (a,a,c);
209 A (c,b,d);
210 Z (b,b,d);
211 S (d,e);
212 S (f,a);
213 M (a,c,a);
214 M (c,b,e);
215 A (e,a,c);
216 Z (a,a,c);
217 S (b,a);
218 Z (c,d,f);
219 M (a,c,_121665);
220 A (a,a,d);
221 M (c,c,a);
222 M (a,d,f);
223 M (d,b,x);
224 S (b,e);
225 sel25519 (a,b,r);
226 sel25519 (c,d,r);
227 }
228 FOR (i,16) {
229 x[i + 16] = a[i];
230 x[i + 32] = c[i];
231 x[i + 48] = b[i];
232 x[i + 64] = d[i];
233 }
234 inv25519 (x + 32,x + 32);
235 M (x + 16,x + 16,x + 32);
236 pack25519 (q,x + 16);
237 return 0;
238}
239
240int crypto_scalarmult_base (u8 *q,const u8 *n)
241{
242 return crypto_scalarmult (q,n,_9);
243}
244
245int crypto_box_keypair (u8 *y,u8 *x)
246{
247 randombytes (x,32);
248 return crypto_scalarmult_base (y,x);
249}
250
251int crypto_hash (u8 *out,const u8 *m,u64 n)
252{
253 struct GNUNET_HashCode *hc = (void *) out;
254 GNUNET_CRYPTO_hash (m, n, hc);
255 return 0;
256}
257
258sv add (gf p[4],gf q[4])
259{
260 gf a,b,c,d,t,e,f,g,h;
261
262 Z (a, p[1], p[0]);
263 Z (t, q[1], q[0]);
264 M (a, a, t);
265 A (b, p[0], p[1]);
266 A (t, q[0], q[1]);
267 M (b, b, t);
268 M (c, p[3], q[3]);
269 M (c, c, D2);
270 M (d, p[2], q[2]);
271 A (d, d, d);
272 Z (e, b, a);
273 Z (f, d, c);
274 A (g, d, c);
275 A (h, b, a);
276
277 M (p[0], e, f);
278 M (p[1], h, g);
279 M (p[2], g, f);
280 M (p[3], e, h);
281}
282
283sv cswap (gf p[4],gf q[4],u8 b)
284{
285 int i;
286 FOR (i,4)
287 sel25519 (p[i],q[i],b);
288}
289
290sv pack (u8 *r,gf p[4])
291{
292 gf tx, ty, zi;
293 inv25519 (zi, p[2]);
294 M (tx, p[0], zi);
295 M (ty, p[1], zi);
296 pack25519 (r, ty);
297 r[31] ^= par25519 (tx) << 7;
298}
299
300sv scalarmult (gf p[4],gf q[4],const u8 *s)
301{
302 int i;
303 set25519 (p[0],gf0);
304 set25519 (p[1],gf1);
305 set25519 (p[2],gf1);
306 set25519 (p[3],gf0);
307 for (i = 255; i >= 0; --i) {
308 u8 b = (s[i / 8] >> (i & 7)) & 1;
309 cswap (p,q,b);
310 add (q,p);
311 add (p,p);
312 cswap (p,q,b);
313 }
314}
315
316sv scalarbase (gf p[4],const u8 *s)
317{
318 gf q[4];
319 set25519 (q[0],X);
320 set25519 (q[1],Y);
321 set25519 (q[2],gf1);
322 M (q[3],X,Y);
323 scalarmult (p,q,s);
324}
325
326static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6,
327 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0,
328 0, 0, 0, 0, 0, 0, 0, 0,
329 0, 0, 0, 0x10};
330
331sv modL (u8 *r,i64 x[64])
332{
333 i64 carry,i,j;
334 for (i = 63; i >= 32; --i) {
335 carry = 0;
336 for (j = i - 32; j < i - 12; ++j) {
337 x[j] += carry - 16 * x[i] * L[j - (i - 32)];
338 carry = (x[j] + 128) >> 8;
339 x[j] -= carry << 8;
340 }
341 x[j] += carry;
342 x[i] = 0;
343 }
344 carry = 0;
345 FOR (j,32) {
346 x[j] += carry - (x[31] >> 4) * L[j];
347 carry = x[j] >> 8;
348 x[j] &= 255;
349 }
350 FOR (j,32) x[j] -= carry * L[j];
351 FOR (i,32) {
352 x[i + 1] += x[i] >> 8;
353 r[i] = x[i] & 255;
354 }
355}
356
357sv reduce (u8 *r)
358{
359 i64 x[64],i;
360 FOR (i,64) x[i] = (u64) r[i];
361 FOR (i,64) r[i] = 0;
362 modL (r,x);
363}
364
365static int unpackneg (gf r[4],const u8 p[32])
366{
367 gf t, chk, num, den, den2, den4, den6;
368 set25519 (r[2],gf1);
369 unpack25519 (r[1],p);
370 S (num,r[1]);
371 M (den,num,D);
372 Z (num,num,r[2]);
373 A (den,r[2],den);
374
375 S (den2,den);
376 S (den4,den2);
377 M (den6,den4,den2);
378 M (t,den6,num);
379 M (t,t,den);
380
381 pow2523 (t,t);
382 M (t,t,num);
383 M (t,t,den);
384 M (t,t,den);
385 M (r[0],t,den);
386
387 S (chk,r[0]);
388 M (chk,chk,den);
389 if (neq25519 (chk, num))
390 M (r[0],r[0],I);
391
392 S (chk,r[0]);
393 M (chk,chk,den);
394 if (neq25519 (chk, num))
395 return -1;
396
397 if (par25519 (r[0]) == (p[31] >> 7))
398 Z (r[0],gf0,r[0]);
399
400 M (r[3],r[0],r[1]);
401 return 0;
402}
403
404/* The following functions have been added for GNUnet */
405
406void
407crypto_sign_pk_from_seed (u8 *pk, const u8 *seed)
408{
409 u8 d[64];
410 gf p[4];
411
412 crypto_hash (d, seed, 32);
413 d[0] &= 248;
414 d[31] &= 127;
415 d[31] |= 64;
416
417 scalarbase (p,d);
418 pack (pk,p);
419}
420
421void
422crypto_sign_sk_from_seed (u8 *sk, const u8 *seed)
423{
424 u8 d[64];
425 gf p[4];
426 u8 pk[32];
427 int i;
428
429 crypto_hash (d, seed, 32);
430 d[0] &= 248;
431 d[31] &= 127;
432 d[31] |= 64;
433
434 scalarbase (p,d);
435 pack (pk,p);
436
437 FOR (i,32) sk[i] = seed[i];
438 FOR (i,32) sk[32 + i] = pk[i];
439}
440
441
442int
443crypto_sign_ed25519_pk_to_curve25519 (u8 *x25519_pk, const u8 *ed25519_pk)
444{
445 gf ge_a[4];
446 gf x;
447 gf one_minus_y;
448
449 if (0 != unpackneg (ge_a, ed25519_pk))
450 return -1;
451
452 set25519 (one_minus_y, gf1);
453 Z (one_minus_y, one_minus_y, ge_a[1]);
454
455 set25519 (x, gf1);
456 A (x, x, ge_a[1]);
457
458 inv25519 (one_minus_y, one_minus_y);
459 M (x, x, one_minus_y);
460 pack25519 (x25519_pk, x);
461
462 return 0;
463}
464
465
466int crypto_sign_detached_verify (const u8 *sig,const u8 *m,u64 n,const u8 *pk)
467{
468 struct GNUNET_HashContext *hc;
469 u8 t[32],h[64];
470 gf p[4],q[4];
471
472 if (unpackneg (q,pk))
473 return -1;
474
475 hc = GNUNET_CRYPTO_hash_context_start ();
476 GNUNET_CRYPTO_hash_context_read (hc, sig, 32);
477 GNUNET_CRYPTO_hash_context_read (hc, pk, 32);
478 GNUNET_CRYPTO_hash_context_read (hc, m, n);
479 GNUNET_CRYPTO_hash_context_finish (hc, (void *) h);
480
481 reduce (h);
482 scalarmult (p,q,h);
483
484 scalarbase (q,sig+32);
485 add (p,q);
486 pack (t,p);
487
488 if (crypto_verify_32 (sig, t))
489 return -1;
490 return 0;
491}
492
493
494int
495crypto_sign_detached (u8 *sig,const u8 *m,u64 n,const u8 *sk)
496{
497 struct GNUNET_HashContext *hc;
498 u8 d[64],h[64],r[64];
499 i64 i,j,x[64];
500 gf p[4];
501
502 crypto_hash (d, sk, 32);
503 d[0] &= 248;
504 d[31] &= 127;
505 d[31] |= 64;
506
507 hc = GNUNET_CRYPTO_hash_context_start ();
508 GNUNET_CRYPTO_hash_context_read (hc, d + 32, 32);
509 GNUNET_CRYPTO_hash_context_read (hc, m, n);
510 GNUNET_CRYPTO_hash_context_finish (hc, (void *) r);
511
512 reduce (r);
513 scalarbase (p,r);
514 pack (sig,p);
515
516 hc = GNUNET_CRYPTO_hash_context_start ();
517 GNUNET_CRYPTO_hash_context_read (hc, sig, 32);
518 GNUNET_CRYPTO_hash_context_read (hc, sk + 32, 32);
519 GNUNET_CRYPTO_hash_context_read (hc, m, n);
520 GNUNET_CRYPTO_hash_context_finish (hc, (void *) h);
521
522 reduce (h);
523
524 FOR (i,64) x[i] = 0;
525 FOR (i,32) x[i] = (u64) r[i];
526 FOR (i,32) FOR (j,32) x[i + j] += h[i] * (u64) d[j];
527 modL (sig + 32,x);
528
529 return 0;
530}
diff --git a/src/util/tweetnacl-gnunet.h b/src/util/tweetnacl-gnunet.h
new file mode 100644
index 000000000..776e0d355
--- /dev/null
+++ b/src/util/tweetnacl-gnunet.h
@@ -0,0 +1,85 @@
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
10
11#ifndef TWEETNACL_H
12#define TWEETNACL_H
13#include <stdint.h>
14#define crypto_scalarmult_PRIMITIVE "curve25519"
15#define crypto_scalarmult crypto_scalarmult_curve25519
16#define crypto_scalarmult_base crypto_scalarmult_curve25519_base
17#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES
18#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES
19#define crypto_scalarmult_IMPLEMENTATION \
20 crypto_scalarmult_curve25519_IMPLEMENTATION
21#define crypto_scalarmult_VERSION crypto_scalarmult_curve25519_VERSION
22#define crypto_scalarmult_curve25519_tweet_BYTES 32
23#define crypto_scalarmult_curve25519_tweet_SCALARBYTES 32
24extern int crypto_scalarmult_curve25519_tweet (uint8_t *,
25 const uint8_t *,
26 const uint8_t *);
27extern int crypto_scalarmult_curve25519_tweet_base (uint8_t *,
28 const uint8_t *);
29#define crypto_scalarmult_curve25519_tweet_VERSION "-"
30#define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tweet
31#define crypto_scalarmult_curve25519_base \
32 crypto_scalarmult_curve25519_tweet_base
33#define crypto_scalarmult_curve25519_BYTES \
34 crypto_scalarmult_curve25519_tweet_BYTES
35#define crypto_scalarmult_curve25519_SCALARBYTES \
36 crypto_scalarmult_curve25519_tweet_SCALARBYTES
37#define crypto_scalarmult_curve25519_VERSION \
38 crypto_scalarmult_curve25519_tweet_VERSION
39#define crypto_scalarmult_curve25519_IMPLEMENTATION \
40 "crypto_scalarmult/curve25519/tweet"
41#define crypto_sign_PRIMITIVE "ed25519"
42#define crypto_sign crypto_sign_ed25519
43#define crypto_sign_BYTES crypto_sign_ed25519_BYTES
44#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES
45#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES
46#define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION
47#define crypto_sign_VERSION crypto_sign_ed25519_VERSION
48#define crypto_sign_ed25519_tweet_BYTES 64
49#define crypto_sign_ed25519_tweet_PUBLICKEYBYTES 32
50#define crypto_sign_ed25519_tweet_SECRETKEYBYTES 64
51extern int crypto_sign_ed25519_tweet (uint8_t *,
52 uint64_t *,
53 const uint8_t *,
54 uint64_t,
55 const uint8_t *);
56extern int crypto_sign_ed25519_tweet_open (uint8_t *,
57 uint64_t *,
58 const uint8_t *,
59 uint64_t,
60 const uint8_t *);
61extern int crypto_sign_ed25519_tweet_keypair (uint8_t *,uint8_t *);
62#define crypto_sign_ed25519_tweet_VERSION "-"
63#define crypto_sign_ed25519 crypto_sign_ed25519_tweet
64#define crypto_sign_ed25519_open crypto_sign_ed25519_tweet_open
65#define crypto_sign_ed25519_keypair crypto_sign_ed25519_tweet_keypair
66#define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tweet_BYTES
67#define crypto_sign_ed25519_PUBLICKEYBYTES \
68 crypto_sign_ed25519_tweet_PUBLICKEYBYTES
69#define crypto_sign_ed25519_SECRETKEYBYTES \
70 crypto_sign_ed25519_tweet_SECRETKEYBYTES
71#define crypto_sign_ed25519_VERSION crypto_sign_ed25519_tweet_VERSION
72#define crypto_sign_ed25519_IMPLEMENTATION "crypto_sign/ed25519/tweet"
73void crypto_sign_pk_from_seed (uint8_t *pk, const uint8_t *seed);
74void crypto_sign_sk_from_seed (uint8_t *sk, const uint8_t *seed);
75int crypto_sign_ed25519_pk_to_curve25519 (uint8_t *x25519_pk,
76 const uint8_t *ed25519_pk);
77int crypto_sign_detached_verify (const uint8_t *sig,
78 const uint8_t *m,
79 uint64_t n,
80 const uint8_t *pk);
81int crypto_sign_detached (uint8_t *sig,
82 const uint8_t *m,
83 uint64_t n,
84 const uint8_t *sk);
85#endif