aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-04-18 21:11:08 +0200
committerChristian Grothoff <christian@grothoff.org>2021-04-18 21:11:08 +0200
commit75cfa6370bc902765c26b50bb858c9a5bc1e8e48 (patch)
treefdadaf6e2736ad79c9f79576bf9a056ea9d0a6f5 /src
parent5ec7af75ea9f8ed86cf28a8efed9a917345d1681 (diff)
downloadgnunet-75cfa6370bc902765c26b50bb858c9a5bc1e8e48.tar.gz
gnunet-75cfa6370bc902765c26b50bb858c9a5bc1e8e48.zip
SCALARPRODUCT: migrating logic from libgcrypt to libsodium (#6818).
Diffstat (limited to 'src')
-rw-r--r--src/include/gnunet_crypto_lib.h132
-rw-r--r--src/include/gnunet_scalarproduct_service.h50
-rw-r--r--src/scalarproduct/Makefile.am4
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c297
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c131
-rwxr-xr-xsrc/scalarproduct/perf_scalarproduct.sh19
-rw-r--r--src/scalarproduct/scalarproduct_api.c50
-rw-r--r--src/scalarproduct/test_ecc_scalarproduct.c211
-rwxr-xr-xsrc/scalarproduct/test_scalarproduct_negative.sh3
-rw-r--r--src/util/Makefile.am3
-rw-r--r--src/util/crypto_ecc_dlog.c525
-rw-r--r--src/util/perf_crypto_ecc_dlog.c118
-rw-r--r--src/util/test_crypto_ecc_dlog.c141
13 files changed, 767 insertions, 917 deletions
diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h
index d01457b4a..2a552e212 100644
--- a/src/include/gnunet_crypto_lib.h
+++ b/src/include/gnunet_crypto_lib.h
@@ -1443,9 +1443,16 @@ struct GNUNET_CRYPTO_EccPoint
1443 * Q consists of an x- and a y-value, each mod p (256 bits), given 1443 * Q consists of an x- and a y-value, each mod p (256 bits), given
1444 * here in affine coordinates and Ed25519 standard compact format. 1444 * here in affine coordinates and Ed25519 standard compact format.
1445 */ 1445 */
1446 unsigned char q_y[256 / 8]; 1446 unsigned char v[256 / 8];
1447}; 1447};
1448 1448
1449/**
1450 * A ECC scalar for use in point multiplications
1451 */
1452struct GNUNET_CRYPTO_EccScalar
1453{
1454 unsigned char v[256 / 8];
1455};
1449 1456
1450/** 1457/**
1451 * Do pre-calculation for ECC discrete logarithm for small factors. 1458 * Do pre-calculation for ECC discrete logarithm for small factors.
@@ -1455,7 +1462,8 @@ struct GNUNET_CRYPTO_EccPoint
1455 * @return NULL on error 1462 * @return NULL on error
1456 */ 1463 */
1457struct GNUNET_CRYPTO_EccDlogContext * 1464struct GNUNET_CRYPTO_EccDlogContext *
1458GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, unsigned int mem); 1465GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max,
1466 unsigned int mem);
1459 1467
1460 1468
1461/** 1469/**
@@ -1468,7 +1476,7 @@ GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, unsigned int mem);
1468 */ 1476 */
1469int 1477int
1470GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, 1478GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
1471 gcry_mpi_point_t input); 1479 const struct GNUNET_CRYPTO_EccPoint *input);
1472 1480
1473 1481
1474/** 1482/**
@@ -1479,138 +1487,107 @@ GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
1479 * convert a point back to an integer (as long as the 1487 * convert a point back to an integer (as long as the
1480 * integer is smaller than the MAX of the @a edc context). 1488 * integer is smaller than the MAX of the @a edc context).
1481 * 1489 *
1482 * @param edc calculation context for ECC operations
1483 * @param val value to encode into a point 1490 * @param val value to encode into a point
1484 * @return representation of the value as an ECC point, 1491 * @param r where to write the point (must be allocated)
1485 * must be freed using #GNUNET_CRYPTO_ecc_free()
1486 */ 1492 */
1487gcry_mpi_point_t 1493void
1488GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc, int val); 1494GNUNET_CRYPTO_ecc_dexp (int val,
1495 struct GNUNET_CRYPTO_EccPoint*r);
1489 1496
1490 1497
1491/** 1498/**
1492 * Multiply the generator g of the elliptic curve by @a val 1499 * Multiply the generator g of the elliptic curve by @a val
1493 * to obtain the point on the curve representing @a val. 1500 * to obtain the point on the curve representing @a val.
1494 * 1501 *
1495 * @param edc calculation context for ECC operations
1496 * @param val (positive) value to encode into a point 1502 * @param val (positive) value to encode into a point
1497 * @return representation of the value as an ECC point, 1503 * @param r where to write the point (must be allocated)
1498 * must be freed using #GNUNET_CRYPTO_ecc_free() 1504 * @return #GNUNET_OK on success.
1499 */ 1505 */
1500gcry_mpi_point_t 1506enum GNUNET_GenericReturnValue
1501GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc, 1507GNUNET_CRYPTO_ecc_dexp_mpi (const struct GNUNET_CRYPTO_EccScalar *val,
1502 gcry_mpi_t val); 1508 struct GNUNET_CRYPTO_EccPoint *r);
1503 1509
1504 1510
1505/** 1511/**
1506 * Multiply the point @a p on the elliptic curve by @a val. 1512 * Multiply the point @a p on the elliptic curve by @a val.
1507 * 1513 *
1508 * @param edc calculation context for ECC operations
1509 * @param p point to multiply 1514 * @param p point to multiply
1510 * @param val (positive) value to encode into a point 1515 * @param val (positive) value to encode into a point
1511 * @return representation of the value as an ECC point, 1516 * @param r where to write the point (must be allocated)
1512 * must be freed using #GNUNET_CRYPTO_ecc_free() 1517 * @return #GNUNET_OK on success.
1513 */
1514gcry_mpi_point_t
1515GNUNET_CRYPTO_ecc_pmul_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
1516 gcry_mpi_point_t p,
1517 gcry_mpi_t val);
1518
1519
1520/**
1521 * Convert point value to binary representation.
1522 *
1523 * @param edc calculation context for ECC operations
1524 * @param point computational point representation
1525 * @param[out] bin binary point representation
1526 */
1527void
1528GNUNET_CRYPTO_ecc_point_to_bin (struct GNUNET_CRYPTO_EccDlogContext *edc,
1529 gcry_mpi_point_t point,
1530 struct GNUNET_CRYPTO_EccPoint *bin);
1531
1532
1533/**
1534 * Convert binary representation of a point to computational representation.
1535 *
1536 * @param edc calculation context for ECC operations
1537 * @param bin binary point representation
1538 * @return computational representation
1539 */ 1518 */
1540gcry_mpi_point_t 1519enum GNUNET_GenericReturnValue
1541GNUNET_CRYPTO_ecc_bin_to_point (struct GNUNET_CRYPTO_EccDlogContext *edc, 1520GNUNET_CRYPTO_ecc_pmul_mpi (const struct GNUNET_CRYPTO_EccPoint *p,
1542 const struct GNUNET_CRYPTO_EccPoint *bin); 1521 const struct GNUNET_CRYPTO_EccScalar *val,
1522 struct GNUNET_CRYPTO_EccPoint *r);
1543 1523
1544 1524
1545/** 1525/**
1546 * Add two points on the elliptic curve. 1526 * Add two points on the elliptic curve.
1547 * 1527 *
1548 * @param edc calculation context for ECC operations
1549 * @param a some value 1528 * @param a some value
1550 * @param b some value 1529 * @param b some value
1551 * @return @a a + @a b, must be freed using #GNUNET_CRYPTO_ecc_free() 1530 * @param r where to write the point (must be allocated)
1531 * @return #GNUNET_OK on success.
1552 */ 1532 */
1553gcry_mpi_point_t 1533enum GNUNET_GenericReturnValue
1554GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc, 1534GNUNET_CRYPTO_ecc_add (const struct GNUNET_CRYPTO_EccPoint *a,
1555 gcry_mpi_point_t a, 1535 const struct GNUNET_CRYPTO_EccPoint *b,
1556 gcry_mpi_point_t b); 1536 struct GNUNET_CRYPTO_EccPoint *r);
1557 1537
1558 1538
1559/** 1539/**
1560 * Obtain a random point on the curve and its 1540 * Obtain a random point on the curve and its
1561 * additive inverse. Both returned values 1541 * additive inverse.
1562 * must be freed using #GNUNET_CRYPTO_ecc_free().
1563 * 1542 *
1564 * @param edc calculation context for ECC operations
1565 * @param[out] r set to a random point on the curve 1543 * @param[out] r set to a random point on the curve
1566 * @param[out] r_inv set to the additive inverse of @a r 1544 * @param[out] r_inv set to the additive inverse of @a r
1545 * @return #GNUNET_OK on success.
1567 */ 1546 */
1568void 1547enum GNUNET_GenericReturnValue
1569GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccDlogContext *edc, 1548GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccPoint *r,
1570 gcry_mpi_point_t *r, 1549 struct GNUNET_CRYPTO_EccPoint *r_inv);
1571 gcry_mpi_point_t *r_inv);
1572 1550
1573 1551
1574/** 1552/**
1575 * Obtain a random scalar for point multiplication on the curve and 1553 * Obtain a random scalar for point multiplication on the curve and
1576 * its multiplicative inverse. 1554 * its additive inverse.
1577 * 1555 *
1578 * @param edc calculation context for ECC operations
1579 * @param[out] r set to a random scalar on the curve 1556 * @param[out] r set to a random scalar on the curve
1580 * @param[out] r_inv set to the multiplicative inverse of @a r 1557 * @param[out] r_neg set to the negation of @a
1581 */ 1558 */
1582void 1559void
1583GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc, 1560GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccScalar *r,
1584 gcry_mpi_t *r, 1561 struct GNUNET_CRYPTO_EccScalar *r_neg);
1585 gcry_mpi_t *r_inv);
1586 1562
1587 1563
1588/** 1564/**
1589 * Generate a random value mod n. 1565 * Generate a random value mod n.
1590 * 1566 *
1591 * @param edc ECC context 1567 * @param[out] r random value mod n.
1592 * @return random value mod n.
1593 */ 1568 */
1594gcry_mpi_t 1569void
1595GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc); 1570GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccScalar*r);
1596 1571
1597 1572
1598/** 1573/**
1599 * Free a point value returned by the API. 1574 * Release precalculated values.
1600 * 1575 *
1601 * @param p point to free 1576 * @param dlc dlog context
1602 */ 1577 */
1603void 1578void
1604GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p); 1579GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *dlc);
1605 1580
1606 1581
1607/** 1582/**
1608 * Release precalculated values. 1583 * Create a scalar from int value.
1609 * 1584 *
1610 * @param dlc dlog context 1585 * @param val the int value
1586 * @param[out] r where to write the salar
1611 */ 1587 */
1612void 1588void
1613GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *dlc); 1589GNUNET_CRYPTO_ecc_scalar_from_int (int64_t val,
1590 struct GNUNET_CRYPTO_EccScalar *r);
1614 1591
1615 1592
1616/** 1593/**
@@ -1643,6 +1620,7 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1643 const struct GNUNET_CRYPTO_EcdhePublicKey *pub, 1620 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1644 struct GNUNET_HashCode *key_material); 1621 struct GNUNET_HashCode *key_material);
1645 1622
1623
1646/** 1624/**
1647 * @ingroup crypto 1625 * @ingroup crypto
1648 * Derive key material from a ECDH public key and a private ECDSA key. 1626 * Derive key material from a ECDH public key and a private ECDSA key.
@@ -1937,7 +1915,9 @@ GNUNET_CRYPTO_ecdsa_public_key_derive (
1937 * @param val value to write to @a buf 1915 * @param val value to write to @a buf
1938 */ 1916 */
1939void 1917void
1940GNUNET_CRYPTO_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val); 1918GNUNET_CRYPTO_mpi_print_unsigned (void *buf,
1919 size_t size,
1920 gcry_mpi_t val);
1941 1921
1942 1922
1943/** 1923/**
diff --git a/src/include/gnunet_scalarproduct_service.h b/src/include/gnunet_scalarproduct_service.h
index b12a19a2f..1d775f659 100644
--- a/src/include/gnunet_scalarproduct_service.h
+++ b/src/include/gnunet_scalarproduct_service.h
@@ -17,7 +17,6 @@
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19 */ 19 */
20
21/** 20/**
22 * @author Christian M. Fuchs 21 * @author Christian M. Fuchs
23 * @author Gaurav Kukreja 22 * @author Gaurav Kukreja
@@ -118,10 +117,9 @@ GNUNET_NETWORK_STRUCT_END
118 * @param status Status of the request 117 * @param status Status of the request
119 */ 118 */
120typedef void 119typedef void
121(*GNUNET_SCALARPRODUCT_ContinuationWithStatus) (void *cls, 120(*GNUNET_SCALARPRODUCT_ContinuationWithStatus) (
122 enum 121 void *cls,
123 GNUNET_SCALARPRODUCT_ResponseStatus 122 enum GNUNET_SCALARPRODUCT_ResponseStatus status);
124 status);
125 123
126 124
127/** 125/**
@@ -132,10 +130,10 @@ typedef void
132 * @param result result of the computation 130 * @param result result of the computation
133 */ 131 */
134typedef void 132typedef void
135(*GNUNET_SCALARPRODUCT_DatumProcessor) (void *cls, 133(*GNUNET_SCALARPRODUCT_DatumProcessor) (
136 enum GNUNET_SCALARPRODUCT_ResponseStatus 134 void *cls,
137 status, 135 enum GNUNET_SCALARPRODUCT_ResponseStatus status,
138 gcry_mpi_t result); 136 gcry_mpi_t result);
139 137
140 138
141/** 139/**
@@ -157,16 +155,14 @@ struct GNUNET_SCALARPRODUCT_ComputationHandle;
157 * @return a new handle for this computation 155 * @return a new handle for this computation
158 */ 156 */
159struct GNUNET_SCALARPRODUCT_ComputationHandle * 157struct GNUNET_SCALARPRODUCT_ComputationHandle *
160GNUNET_SCALARPRODUCT_start_computation (const struct 158GNUNET_SCALARPRODUCT_start_computation (
161 GNUNET_CONFIGURATION_Handle *cfg, 159 const struct GNUNET_CONFIGURATION_Handle *cfg,
162 const struct 160 const struct GNUNET_HashCode *session_key,
163 GNUNET_HashCode *session_key, 161 const struct GNUNET_PeerIdentity *peer,
164 const struct GNUNET_PeerIdentity *peer, 162 const struct GNUNET_SCALARPRODUCT_Element *elements,
165 const struct 163 uint32_t element_count,
166 GNUNET_SCALARPRODUCT_Element *elements, 164 GNUNET_SCALARPRODUCT_DatumProcessor cont,
167 uint32_t element_count, 165 void *cont_cls);
168 GNUNET_SCALARPRODUCT_DatumProcessor cont,
169 void *cont_cls);
170 166
171 167
172/** 168/**
@@ -181,15 +177,13 @@ GNUNET_SCALARPRODUCT_start_computation (const struct
181 * @return a new handle for this computation 177 * @return a new handle for this computation
182 */ 178 */
183struct GNUNET_SCALARPRODUCT_ComputationHandle * 179struct GNUNET_SCALARPRODUCT_ComputationHandle *
184GNUNET_SCALARPRODUCT_accept_computation (const struct 180GNUNET_SCALARPRODUCT_accept_computation (
185 GNUNET_CONFIGURATION_Handle *cfg, 181 const struct GNUNET_CONFIGURATION_Handle *cfg,
186 const struct GNUNET_HashCode *key, 182 const struct GNUNET_HashCode *key,
187 const struct 183 const struct GNUNET_SCALARPRODUCT_Element *elements,
188 GNUNET_SCALARPRODUCT_Element *elements, 184 uint32_t element_count,
189 uint32_t element_count, 185 GNUNET_SCALARPRODUCT_ContinuationWithStatus cont,
190 GNUNET_SCALARPRODUCT_ContinuationWithStatus 186 void *cont_cls);
191 cont,
192 void *cont_cls);
193 187
194 188
195/** 189/**
diff --git a/src/scalarproduct/Makefile.am b/src/scalarproduct/Makefile.am
index f3448725a..cf05e8377 100644
--- a/src/scalarproduct/Makefile.am
+++ b/src/scalarproduct/Makefile.am
@@ -63,6 +63,7 @@ gnunet_service_scalarproduct_ecc_alice_LDADD = \
63 $(top_builddir)/src/cadet/libgnunetcadet.la \ 63 $(top_builddir)/src/cadet/libgnunetcadet.la \
64 $(top_builddir)/src/seti/libgnunetseti.la \ 64 $(top_builddir)/src/seti/libgnunetseti.la \
65 $(LIBGCRYPT_LIBS) \ 65 $(LIBGCRYPT_LIBS) \
66 -lsodium \
66 -lgcrypt \ 67 -lgcrypt \
67 $(GN_LIBINTL) 68 $(GN_LIBINTL)
68 69
@@ -74,6 +75,7 @@ gnunet_service_scalarproduct_ecc_bob_LDADD = \
74 $(top_builddir)/src/cadet/libgnunetcadet.la \ 75 $(top_builddir)/src/cadet/libgnunetcadet.la \
75 $(top_builddir)/src/seti/libgnunetseti.la \ 76 $(top_builddir)/src/seti/libgnunetseti.la \
76 $(LIBGCRYPT_LIBS) \ 77 $(LIBGCRYPT_LIBS) \
78 -lsodium \
77 -lgcrypt \ 79 -lgcrypt \
78 $(GN_LIBINTL) 80 $(GN_LIBINTL)
79 81
@@ -111,4 +113,4 @@ test_ecc_scalarproduct_SOURCES = \
111 test_ecc_scalarproduct.c 113 test_ecc_scalarproduct.c
112test_ecc_scalarproduct_LDADD = \ 114test_ecc_scalarproduct_LDADD = \
113 $(top_builddir)/src/util/libgnunetutil.la \ 115 $(top_builddir)/src/util/libgnunetutil.la \
114 -lgcrypt 116 -lsodium
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
index 447451aef..e33d589be 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013-2017 GNUnet e.V. 3 Copyright (C) 2013-2017, 2021 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -69,7 +69,7 @@ struct MpiElement
69 /** 69 /**
70 * a_i value, not disclosed to Bob. 70 * a_i value, not disclosed to Bob.
71 */ 71 */
72 gcry_mpi_t value; 72 int64_t value;
73}; 73};
74 74
75 75
@@ -138,9 +138,9 @@ struct AliceServiceSession
138 struct MpiElement *sorted_elements; 138 struct MpiElement *sorted_elements;
139 139
140 /** 140 /**
141 * The computed scalar 141 * The computed scalar product. INT_MAX if the computation failed.
142 */ 142 */
143 gcry_mpi_t product; 143 int product;
144 144
145 /** 145 /**
146 * How many elements we were supplied with from the client (total 146 * How many elements we were supplied with from the client (total
@@ -190,12 +190,12 @@ static struct GNUNET_CRYPTO_EccDlogContext *edc;
190/** 190/**
191 * Alice's private key ('a'). 191 * Alice's private key ('a').
192 */ 192 */
193static gcry_mpi_t my_privkey; 193static struct GNUNET_CRYPTO_EccScalar my_privkey;
194 194
195/** 195/**
196 * Inverse of Alice's private key ('a_inv'). 196 * Inverse of Alice's private key ('a_inv').
197 */ 197 */
198static gcry_mpi_t my_privkey_inv; 198static struct GNUNET_CRYPTO_EccScalar my_privkey_inv;
199 199
200/** 200/**
201 * Handle to the CADET service. 201 * Handle to the CADET service.
@@ -212,7 +212,9 @@ static struct GNUNET_CADET_Handle *my_cadet;
212 * @return #GNUNET_OK (continue to iterate) 212 * @return #GNUNET_OK (continue to iterate)
213 */ 213 */
214static int 214static int
215free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value) 215free_element_cb (void *cls,
216 const struct GNUNET_HashCode *key,
217 void *value)
216{ 218{
217 struct GNUNET_SCALARPRODUCT_Element *e = value; 219 struct GNUNET_SCALARPRODUCT_Element *e = value;
218 220
@@ -229,8 +231,6 @@ free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
229static void 231static void
230destroy_service_session (struct AliceServiceSession *s) 232destroy_service_session (struct AliceServiceSession *s)
231{ 233{
232 unsigned int i;
233
234 if (GNUNET_YES == s->in_destroy) 234 if (GNUNET_YES == s->in_destroy)
235 return; 235 return;
236 s->in_destroy = GNUNET_YES; 236 s->in_destroy = GNUNET_YES;
@@ -261,7 +261,8 @@ destroy_service_session (struct AliceServiceSession *s)
261 } 261 }
262 if (NULL != s->intersection_op) 262 if (NULL != s->intersection_op)
263 { 263 {
264 LOG (GNUNET_ERROR_TYPE_DEBUG, "Set intersection, op still ongoing!\n"); 264 LOG (GNUNET_ERROR_TYPE_DEBUG,
265 "Set intersection, op still ongoing!\n");
265 GNUNET_SETI_operation_cancel (s->intersection_op); 266 GNUNET_SETI_operation_cancel (s->intersection_op);
266 s->intersection_op = NULL; 267 s->intersection_op = NULL;
267 } 268 }
@@ -272,16 +273,9 @@ destroy_service_session (struct AliceServiceSession *s)
272 } 273 }
273 if (NULL != s->sorted_elements) 274 if (NULL != s->sorted_elements)
274 { 275 {
275 for (i = 0; i < s->used_element_count; i++)
276 gcry_mpi_release (s->sorted_elements[i].value);
277 GNUNET_free (s->sorted_elements); 276 GNUNET_free (s->sorted_elements);
278 s->sorted_elements = NULL; 277 s->sorted_elements = NULL;
279 } 278 }
280 if (NULL != s->product)
281 {
282 gcry_mpi_release (s->product);
283 s->product = NULL;
284 }
285 GNUNET_free (s); 279 GNUNET_free (s);
286} 280}
287 281
@@ -305,10 +299,12 @@ prepare_client_end_notification (struct AliceServiceSession *session)
305 "Sending session-end notification with status %d to client for session %s\n", 299 "Sending session-end notification with status %d to client for session %s\n",
306 session->status, 300 session->status,
307 GNUNET_h2s (&session->session_id)); 301 GNUNET_h2s (&session->session_id));
308 e = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT); 302 e = GNUNET_MQ_msg (msg,
303 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_RESULT);
309 msg->product_length = htonl (0); 304 msg->product_length = htonl (0);
310 msg->status = htonl (session->status); 305 msg->status = htonl (session->status);
311 GNUNET_MQ_send (session->client_mq, e); 306 GNUNET_MQ_send (session->client_mq,
307 e);
312} 308}
313 309
314 310
@@ -327,41 +323,41 @@ transmit_client_response (struct AliceServiceSession *s)
327 size_t product_length = 0; 323 size_t product_length = 0;
328 int32_t range; 324 int32_t range;
329 gcry_error_t rc; 325 gcry_error_t rc;
330 int sign;
331 gcry_mpi_t value; 326 gcry_mpi_t value;
332 327
333 if (NULL == s->product) 328 if (INT_MAX == s->product)
334 { 329 {
335 GNUNET_break (0); 330 GNUNET_break (0);
336 prepare_client_end_notification (s); 331 prepare_client_end_notification (s);
337 return; 332 return;
338 } 333 }
339 value = gcry_mpi_new (0); 334 value = gcry_mpi_new (32);
340 sign = gcry_mpi_cmp_ui (s->product, 0); 335 if (0 > s->product)
341 if (0 > sign)
342 { 336 {
343 range = -1; 337 range = -1;
344 gcry_mpi_sub (value, value, s->product); 338 gcry_mpi_set_ui (value,
339 -s->product);
345 } 340 }
346 else if (0 < sign) 341 else if (0 < s->product)
347 { 342 {
348 range = 1; 343 range = 1;
349 gcry_mpi_add (value, value, s->product); 344 gcry_mpi_set_ui (value,
345 s->product);
350 } 346 }
351 else 347 else
352 { 348 {
353 /* result is exactly zero */ 349 /* result is exactly zero */
354 range = 0; 350 range = 0;
355 } 351 }
356 gcry_mpi_release (s->product); 352 if ( (0 != range) &&
357 s->product = NULL; 353 (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD,
358 354 &product_exported,
359 if ((0 != range) && (0 != (rc = gcry_mpi_aprint (GCRYMPI_FMT_STD, 355 &product_length,
360 &product_exported, 356 value))))
361 &product_length,
362 value))))
363 { 357 {
364 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc); 358 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR,
359 "gcry_mpi_scan",
360 rc);
365 prepare_client_end_notification (s); 361 prepare_client_end_notification (s);
366 return; 362 return;
367 } 363 }
@@ -374,10 +370,13 @@ transmit_client_response (struct AliceServiceSession *s)
374 msg->product_length = htonl (product_length); 370 msg->product_length = htonl (product_length);
375 if (NULL != product_exported) 371 if (NULL != product_exported)
376 { 372 {
377 GNUNET_memcpy (&msg[1], product_exported, product_length); 373 GNUNET_memcpy (&msg[1],
374 product_exported,
375 product_length);
378 GNUNET_free (product_exported); 376 GNUNET_free (product_exported);
379 } 377 }
380 GNUNET_MQ_send (s->client_mq, e); 378 GNUNET_MQ_send (s->client_mq,
379 e);
381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 380 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
382 "Sent result to client, session %s has ended!\n", 381 "Sent result to client, session %s has ended!\n",
383 GNUNET_h2s (&s->session_id)); 382 GNUNET_h2s (&s->session_id));
@@ -394,7 +393,8 @@ transmit_client_response (struct AliceServiceSession *s)
394 * @param channel connection to the other end (henceforth invalid) 393 * @param channel connection to the other end (henceforth invalid)
395 */ 394 */
396static void 395static void
397cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel) 396cb_channel_destruction (void *cls,
397 const struct GNUNET_CADET_Channel *channel)
398{ 398{
399 struct AliceServiceSession *s = cls; 399 struct AliceServiceSession *s = cls;
400 400
@@ -413,51 +413,6 @@ cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel)
413 413
414 414
415/** 415/**
416 * Compute our scalar product, done by Alice
417 *
418 * @param session the session associated with this computation
419 * @param prod_g_i_b_i value from Bob
420 * @param prod_h_i_b_i value from Bob
421 * @return product as MPI, never NULL
422 */
423static gcry_mpi_t
424compute_scalar_product (struct AliceServiceSession *session,
425 gcry_mpi_point_t prod_g_i_b_i,
426 gcry_mpi_point_t prod_h_i_b_i)
427{
428 gcry_mpi_point_t g_i_b_i_a_inv;
429 gcry_mpi_point_t g_ai_bi;
430 int ai_bi;
431 gcry_mpi_t ret;
432
433 g_i_b_i_a_inv =
434 GNUNET_CRYPTO_ecc_pmul_mpi (edc, prod_g_i_b_i, my_privkey_inv);
435 g_ai_bi = GNUNET_CRYPTO_ecc_add (edc, g_i_b_i_a_inv, prod_h_i_b_i);
436 gcry_mpi_point_release (g_i_b_i_a_inv);
437 ai_bi = GNUNET_CRYPTO_ecc_dlog (edc, g_ai_bi);
438 gcry_mpi_point_release (g_ai_bi);
439 if (INT_MAX == ai_bi)
440 {
441 /* result too big */
442 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
443 "Scalar product result out of range\n");
444 return NULL;
445 }
446 ret = gcry_mpi_new (0);
447 if (ai_bi > 0)
448 {
449 gcry_mpi_set_ui (ret, ai_bi);
450 }
451 else
452 {
453 gcry_mpi_set_ui (ret, -ai_bi);
454 gcry_mpi_neg (ret, ret);
455 }
456 return ret;
457}
458
459
460/**
461 * Handle a response we got from another service we wanted to 416 * Handle a response we got from another service we wanted to
462 * calculate a scalarproduct with. 417 * calculate a scalarproduct with.
463 * 418 *
@@ -469,8 +424,6 @@ handle_bobs_cryptodata_message (void *cls,
469 const struct EccBobCryptodataMessage *msg) 424 const struct EccBobCryptodataMessage *msg)
470{ 425{
471 struct AliceServiceSession *s = cls; 426 struct AliceServiceSession *s = cls;
472 gcry_mpi_point_t prod_g_i_b_i;
473 gcry_mpi_point_t prod_h_i_b_i;
474 uint32_t contained; 427 uint32_t contained;
475 428
476 contained = ntohl (msg->contained_element_count); 429 contained = ntohl (msg->contained_element_count);
@@ -494,16 +447,33 @@ handle_bobs_cryptodata_message (void *cls,
494 destroy_service_session (s); 447 destroy_service_session (s);
495 return; 448 return;
496 } 449 }
497
498 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 450 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
499 "Received %u crypto values from Bob\n", 451 "Received %u crypto values from Bob\n",
500 (unsigned int) contained); 452 (unsigned int) contained);
501 GNUNET_CADET_receive_done (s->channel); 453 GNUNET_CADET_receive_done (s->channel);
502 prod_g_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &msg->prod_g_i_b_i); 454 {
503 prod_h_i_b_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, &msg->prod_h_i_b_i); 455 struct GNUNET_CRYPTO_EccPoint g_i_b_i_a_inv;
504 s->product = compute_scalar_product (s, prod_g_i_b_i, prod_h_i_b_i); 456 struct GNUNET_CRYPTO_EccPoint g_ai_bi;
505 gcry_mpi_point_release (prod_g_i_b_i); 457
506 gcry_mpi_point_release (prod_h_i_b_i); 458 GNUNET_assert (
459 GNUNET_OK ==
460 GNUNET_CRYPTO_ecc_pmul_mpi (&msg->prod_g_i_b_i,
461 &my_privkey_inv,
462 &g_i_b_i_a_inv));
463 GNUNET_assert (
464 GNUNET_OK ==
465 GNUNET_CRYPTO_ecc_add (&g_i_b_i_a_inv,
466 &msg->prod_h_i_b_i,
467 &g_ai_bi));
468 s->product = GNUNET_CRYPTO_ecc_dlog (edc,
469 &g_ai_bi);
470 if (INT_MAX == s->product)
471 {
472 /* result too big */
473 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
474 "Scalar product result out of range\n");
475 }
476 }
507 transmit_client_response (s); 477 transmit_client_response (s);
508} 478}
509 479
@@ -517,20 +487,15 @@ handle_bobs_cryptodata_message (void *cls,
517 * @param value the `struct GNUNET_SCALARPRODUCT_Element *` 487 * @param value the `struct GNUNET_SCALARPRODUCT_Element *`
518 */ 488 */
519static int 489static int
520copy_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value) 490copy_element_cb (void *cls,
491 const struct GNUNET_HashCode *key,
492 void *value)
521{ 493{
522 struct AliceServiceSession *s = cls; 494 struct AliceServiceSession *s = cls;
523 struct GNUNET_SCALARPRODUCT_Element *e = value; 495 struct GNUNET_SCALARPRODUCT_Element *e = value;
524 gcry_mpi_t mval;
525 int64_t val;
526 496
527 mval = gcry_mpi_new (0); 497 s->sorted_elements[s->used_element_count].value = (int64_t) GNUNET_ntohll (
528 val = (int64_t) GNUNET_ntohll (e->value); 498 e->value);
529 if (0 > val)
530 gcry_mpi_sub_ui (mval, mval, -val);
531 else
532 gcry_mpi_add_ui (mval, mval, val);
533 s->sorted_elements[s->used_element_count].value = mval;
534 s->sorted_elements[s->used_element_count].key = &e->key; 499 s->sorted_elements[s->used_element_count].key = &e->key;
535 s->used_element_count++; 500 s->used_element_count++;
536 return GNUNET_OK; 501 return GNUNET_OK;
@@ -545,12 +510,14 @@ copy_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value)
545 * @return -1 for a < b, 0 for a=b, 1 for a > b. 510 * @return -1 for a < b, 0 for a=b, 1 for a > b.
546 */ 511 */
547static int 512static int
548element_cmp (const void *a, const void *b) 513element_cmp (const void *a,
514 const void *b)
549{ 515{
550 const struct MpiElement *ma = a; 516 const struct MpiElement *ma = a;
551 const struct MpiElement *mb = b; 517 const struct MpiElement *mb = b;
552 518
553 return GNUNET_CRYPTO_hash_cmp (ma->key, mb->key); 519 return GNUNET_CRYPTO_hash_cmp (ma->key,
520 mb->key);
554} 521}
555 522
556 523
@@ -576,9 +543,8 @@ send_alices_cryptodata_message (struct AliceServiceSession *s)
576 struct EccAliceCryptodataMessage *msg; 543 struct EccAliceCryptodataMessage *msg;
577 struct GNUNET_MQ_Envelope *e; 544 struct GNUNET_MQ_Envelope *e;
578 struct GNUNET_CRYPTO_EccPoint *payload; 545 struct GNUNET_CRYPTO_EccPoint *payload;
579 gcry_mpi_t r_ia; 546 struct GNUNET_CRYPTO_EccScalar r_ia;
580 gcry_mpi_t r_ia_ai; 547 struct GNUNET_CRYPTO_EccScalar r_ia_ai;
581 unsigned int i;
582 unsigned int off; 548 unsigned int off;
583 unsigned int todo_count; 549 unsigned int todo_count;
584 550
@@ -614,31 +580,53 @@ send_alices_cryptodata_message (struct AliceServiceSession *s)
614 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA); 580 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_ALICE_CRYPTODATA);
615 msg->contained_element_count = htonl (todo_count); 581 msg->contained_element_count = htonl (todo_count);
616 payload = (struct GNUNET_CRYPTO_EccPoint *) &msg[1]; 582 payload = (struct GNUNET_CRYPTO_EccPoint *) &msg[1];
617 r_ia = gcry_mpi_new (0); 583 for (unsigned int i = off; i < off + todo_count; i++)
618 r_ia_ai = gcry_mpi_new (0);
619 for (i = off; i < off + todo_count; i++)
620 { 584 {
621 gcry_mpi_t r_i; 585 struct GNUNET_CRYPTO_EccScalar r_i;
622 gcry_mpi_point_t g_i; 586 struct GNUNET_CRYPTO_EccPoint g_i;
623 gcry_mpi_point_t h_i; 587 struct GNUNET_CRYPTO_EccPoint h_i;
624 588
625 r_i = GNUNET_CRYPTO_ecc_random_mod_n (edc); 589 /* r_i = random() mod n */
626 g_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, r_i); 590 GNUNET_CRYPTO_ecc_random_mod_n (&r_i);
591 /* g_i = g^{r_i} */
592 GNUNET_assert (GNUNET_OK ==
593 GNUNET_CRYPTO_ecc_dexp_mpi (&r_i,
594 &g_i));
627 /* r_ia = r_i * a */ 595 /* r_ia = r_i * a */
628 gcry_mpi_mul (r_ia, r_i, my_privkey); 596 crypto_core_ed25519_scalar_mul (r_ia.v,
629 gcry_mpi_release (r_i); 597 r_i.v,
598 my_privkey.v);
630 /* r_ia_ai = r_ia + a_i */ 599 /* r_ia_ai = r_ia + a_i */
631 gcry_mpi_add (r_ia_ai, r_ia, s->sorted_elements[i].value); 600 {
632 h_i = GNUNET_CRYPTO_ecc_dexp_mpi (edc, r_ia_ai); 601 int64_t val = s->sorted_elements[i].value;
633 GNUNET_CRYPTO_ecc_point_to_bin (edc, g_i, &payload[(i - off) * 2]); 602 struct GNUNET_CRYPTO_EccScalar vali;
634 GNUNET_CRYPTO_ecc_point_to_bin (edc, h_i, &payload[(i - off) * 2 + 1]); 603
635 gcry_mpi_point_release (g_i); 604 GNUNET_assert (INT64_MIN != val);
636 gcry_mpi_point_release (h_i); 605 GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
606 &vali);
607 if (val > 0)
608 crypto_core_ed25519_scalar_add (r_ia_ai.v,
609 r_ia.v,
610 vali.v);
611 else
612 crypto_core_ed25519_scalar_sub (r_ia_ai.v,
613 r_ia.v,
614 vali.v);
615 }
616 /* h_i = g^{r_ia_ai} */
617 GNUNET_assert (GNUNET_OK ==
618 GNUNET_CRYPTO_ecc_dexp_mpi (&r_ia_ai,
619 &h_i));
620 memcpy (&payload[(i - off) * 2],
621 &g_i,
622 sizeof (g_i));
623 memcpy (&payload[(i - off) * 2 + 1],
624 &h_i,
625 sizeof (h_i));
637 } 626 }
638 gcry_mpi_release (r_ia);
639 gcry_mpi_release (r_ia_ai);
640 off += todo_count; 627 off += todo_count;
641 GNUNET_MQ_send (s->cadet_mq, e); 628 GNUNET_MQ_send (s->cadet_mq,
629 e);
642 } 630 }
643} 631}
644 632
@@ -740,16 +728,17 @@ cb_intersection_request_alice (void *cls,
740 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 728 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
741 "Received intersection request from %s!\n", 729 "Received intersection request from %s!\n",
742 GNUNET_i2s (other_peer)); 730 GNUNET_i2s (other_peer));
743 if (0 != GNUNET_memcmp (other_peer, &s->peer)) 731 if (0 != GNUNET_memcmp (other_peer,
732 &s->peer))
744 { 733 {
745 GNUNET_break_op (0); 734 GNUNET_break_op (0);
746 return; 735 return;
747 } 736 }
748 s->intersection_op = GNUNET_SETI_accept (request, 737 s->intersection_op
749 (struct 738 = GNUNET_SETI_accept (request,
750 GNUNET_SETI_Option[]){ { 0 } }, 739 (struct GNUNET_SETI_Option[]){ { 0 } },
751 &cb_intersection_element_removed, 740 &cb_intersection_element_removed,
752 s); 741 s);
753 if (NULL == s->intersection_op) 742 if (NULL == s->intersection_op)
754 { 743 {
755 GNUNET_break (0); 744 GNUNET_break (0);
@@ -757,7 +746,9 @@ cb_intersection_request_alice (void *cls,
757 prepare_client_end_notification (s); 746 prepare_client_end_notification (s);
758 return; 747 return;
759 } 748 }
760 if (GNUNET_OK != GNUNET_SETI_commit (s->intersection_op, s->intersection_set)) 749 if (GNUNET_OK !=
750 GNUNET_SETI_commit (s->intersection_op,
751 s->intersection_set))
761 { 752 {
762 GNUNET_break (0); 753 GNUNET_break (0);
763 s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE; 754 s->status = GNUNET_SCALARPRODUCT_STATUS_FAILURE;
@@ -775,12 +766,13 @@ cb_intersection_request_alice (void *cls,
775static void 766static void
776client_request_complete_alice (struct AliceServiceSession *s) 767client_request_complete_alice (struct AliceServiceSession *s)
777{ 768{
778 struct GNUNET_MQ_MessageHandler cadet_handlers[] = 769 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
779 { GNUNET_MQ_hd_fixed_size (bobs_cryptodata_message, 770 GNUNET_MQ_hd_fixed_size (bobs_cryptodata_message,
780 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA, 771 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA,
781 struct EccBobCryptodataMessage, 772 struct EccBobCryptodataMessage,
782 s), 773 s),
783 GNUNET_MQ_handler_end () }; 774 GNUNET_MQ_handler_end ()
775 };
784 struct EccServiceRequestMessage *msg; 776 struct EccServiceRequestMessage *msg;
785 struct GNUNET_MQ_Envelope *e; 777 struct GNUNET_MQ_Envelope *e;
786 struct GNUNET_HashCode set_sid; 778 struct GNUNET_HashCode set_sid;
@@ -982,17 +974,17 @@ handle_alice_client_message (void *cls,
982 s->session_id = msg->session_key; 974 s->session_id = msg->session_key;
983 elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1]; 975 elements = (const struct GNUNET_SCALARPRODUCT_Element *) &msg[1];
984 s->intersected_elements = 976 s->intersected_elements =
985 GNUNET_CONTAINER_multihashmap_create (s->total, GNUNET_YES); 977 GNUNET_CONTAINER_multihashmap_create (s->total,
978 GNUNET_YES);
986 s->intersection_set = GNUNET_SETI_create (cfg); 979 s->intersection_set = GNUNET_SETI_create (cfg);
987 for (uint32_t i = 0; i < contained_count; i++) 980 for (uint32_t i = 0; i < contained_count; i++)
988 { 981 {
989 if (0 == GNUNET_ntohll (elements[i].value)) 982 if (0 == GNUNET_ntohll (elements[i].value))
990 continue; 983 continue;
991 elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element); 984 elem = GNUNET_new (struct GNUNET_SCALARPRODUCT_Element);
992 GNUNET_memcpy (elem, 985 *elem = elements[i];
993 &elements[i], 986 if (GNUNET_SYSERR ==
994 sizeof(struct GNUNET_SCALARPRODUCT_Element)); 987 GNUNET_CONTAINER_multihashmap_put (
995 if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put (
996 s->intersected_elements, 988 s->intersected_elements,
997 &elem->key, 989 &elem->key,
998 elem, 990 elem,
@@ -1006,7 +998,10 @@ handle_alice_client_message (void *cls,
1006 set_elem.data = &elem->key; 998 set_elem.data = &elem->key;
1007 set_elem.size = sizeof(elem->key); 999 set_elem.size = sizeof(elem->key);
1008 set_elem.element_type = 0; 1000 set_elem.element_type = 0;
1009 GNUNET_SETI_add_element (s->intersection_set, &set_elem, NULL, NULL); 1001 GNUNET_SETI_add_element (s->intersection_set,
1002 &set_elem,
1003 NULL,
1004 NULL);
1010 s->used_element_count++; 1005 s->used_element_count++;
1011 } 1006 }
1012 GNUNET_SERVICE_client_continue (s->client); 1007 GNUNET_SERVICE_client_continue (s->client);
@@ -1017,7 +1012,8 @@ handle_alice_client_message (void *cls,
1017 "Received partial client request, waiting for more!\n"); 1012 "Received partial client request, waiting for more!\n");
1018 return; 1013 return;
1019 } 1014 }
1020 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Launching computation\n"); 1015 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1016 "Launching computation\n");
1021 client_request_complete_alice (s); 1017 client_request_complete_alice (s);
1022} 1018}
1023 1019
@@ -1031,7 +1027,8 @@ handle_alice_client_message (void *cls,
1031static void 1027static void
1032shutdown_task (void *cls) 1028shutdown_task (void *cls)
1033{ 1029{
1034 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down, initiating cleanup.\n"); 1030 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1031 "Shutting down, initiating cleanup.\n");
1035 // FIXME: we have to cut our connections to CADET first! 1032 // FIXME: we have to cut our connections to CADET first!
1036 if (NULL != my_cadet) 1033 if (NULL != my_cadet)
1037 { 1034 {
@@ -1109,17 +1106,21 @@ run (void *cls,
1109 struct GNUNET_SERVICE_Handle *service) 1106 struct GNUNET_SERVICE_Handle *service)
1110{ 1107{
1111 cfg = c; 1108 cfg = c;
1112 edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_RESULT, MAX_RAM); 1109 edc = GNUNET_CRYPTO_ecc_dlog_prepare (MAX_RESULT,
1110 MAX_RAM);
1113 /* Select a random 'a' value for Alice */ 1111 /* Select a random 'a' value for Alice */
1114 GNUNET_CRYPTO_ecc_rnd_mpi (edc, &my_privkey, &my_privkey_inv); 1112 GNUNET_CRYPTO_ecc_rnd_mpi (&my_privkey,
1113 &my_privkey_inv);
1115 my_cadet = GNUNET_CADET_connect (cfg); 1114 my_cadet = GNUNET_CADET_connect (cfg);
1116 if (NULL == my_cadet) 1115 if (NULL == my_cadet)
1117 { 1116 {
1118 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Connect to CADET failed\n")); 1117 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1118 _ ("Connect to CADET failed\n"));
1119 GNUNET_SCHEDULER_shutdown (); 1119 GNUNET_SCHEDULER_shutdown ();
1120 return; 1120 return;
1121 } 1121 }
1122 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); 1122 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1123 NULL);
1123} 1124}
1124 1125
1125 1126
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
index 4c835d52a..02a62c164 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2013-2017 GNUnet e.V. 3 Copyright (C) 2013-2017, 2021 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -54,7 +54,7 @@ struct MpiElement
54 /** 54 /**
55 * Value represented (a). 55 * Value represented (a).
56 */ 56 */
57 gcry_mpi_t value; 57 int64_t value;
58}; 58};
59 59
60 60
@@ -104,12 +104,12 @@ struct BobServiceSession
104 /** 104 /**
105 * Product of the g_i^{b_i} 105 * Product of the g_i^{b_i}
106 */ 106 */
107 gcry_mpi_point_t prod_g_i_b_i; 107 struct GNUNET_CRYPTO_EccPoint prod_g_i_b_i;
108 108
109 /** 109 /**
110 * Product of the h_i^{b_i} 110 * Product of the h_i^{b_i}
111 */ 111 */
112 gcry_mpi_point_t prod_h_i_b_i; 112 struct GNUNET_CRYPTO_EccPoint prod_h_i_b_i;
113 113
114 /** 114 /**
115 * How many elements will be supplied in total from the client. 115 * How many elements will be supplied in total from the client.
@@ -213,8 +213,6 @@ free_element_cb (void *cls,
213static void 213static void
214destroy_service_session (struct BobServiceSession *s) 214destroy_service_session (struct BobServiceSession *s)
215{ 215{
216 unsigned int i;
217
218 if (GNUNET_YES == s->in_destroy) 216 if (GNUNET_YES == s->in_destroy)
219 return; 217 return;
220 s->in_destroy = GNUNET_YES; 218 s->in_destroy = GNUNET_YES;
@@ -245,21 +243,9 @@ destroy_service_session (struct BobServiceSession *s)
245 } 243 }
246 if (NULL != s->sorted_elements) 244 if (NULL != s->sorted_elements)
247 { 245 {
248 for (i = 0; i < s->used_element_count; i++)
249 gcry_mpi_release (s->sorted_elements[i].value);
250 GNUNET_free (s->sorted_elements); 246 GNUNET_free (s->sorted_elements);
251 s->sorted_elements = NULL; 247 s->sorted_elements = NULL;
252 } 248 }
253 if (NULL != s->prod_g_i_b_i)
254 {
255 gcry_mpi_point_release (s->prod_g_i_b_i);
256 s->prod_g_i_b_i = NULL;
257 }
258 if (NULL != s->prod_h_i_b_i)
259 {
260 gcry_mpi_point_release (s->prod_h_i_b_i);
261 s->prod_h_i_b_i = NULL;
262 }
263 if (NULL != s->port) 249 if (NULL != s->port)
264 { 250 {
265 GNUNET_CADET_close_port (s->port); 251 GNUNET_CADET_close_port (s->port);
@@ -364,14 +350,8 @@ transmit_bobs_cryptodata_message (struct BobServiceSession *s)
364 e = GNUNET_MQ_msg (msg, 350 e = GNUNET_MQ_msg (msg,
365 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA); 351 GNUNET_MESSAGE_TYPE_SCALARPRODUCT_ECC_BOB_CRYPTODATA);
366 msg->contained_element_count = htonl (2); 352 msg->contained_element_count = htonl (2);
367 if (NULL != s->prod_g_i_b_i) 353 msg->prod_g_i_b_i = s->prod_g_i_b_i;
368 GNUNET_CRYPTO_ecc_point_to_bin (edc, 354 msg->prod_h_i_b_i = s->prod_h_i_b_i;
369 s->prod_g_i_b_i,
370 &msg->prod_g_i_b_i);
371 if (NULL != s->prod_h_i_b_i)
372 GNUNET_CRYPTO_ecc_point_to_bin (edc,
373 s->prod_h_i_b_i,
374 &msg->prod_h_i_b_i);
375 GNUNET_MQ_notify_sent (e, 355 GNUNET_MQ_notify_sent (e,
376 &bob_cadet_done_cb, 356 &bob_cadet_done_cb,
377 s); 357 s);
@@ -384,10 +364,9 @@ transmit_bobs_cryptodata_message (struct BobServiceSession *s)
384 * Iterator to copy over messages from the hash map 364 * Iterator to copy over messages from the hash map
385 * into an array for sorting. 365 * into an array for sorting.
386 * 366 *
387 * @param cls the `struct BobServiceSession *` 367 * @param cls the `struct AliceServiceSession *`
388 * @param key the key (unused) 368 * @param key the key (unused)
389 * @param value the `struct GNUNET_SCALARPRODUCT_Element *` 369 * @param value the `struct GNUNET_SCALARPRODUCT_Element *`
390 * TODO: code duplication with Alice!
391 */ 370 */
392static int 371static int
393copy_element_cb (void *cls, 372copy_element_cb (void *cls,
@@ -396,17 +375,10 @@ copy_element_cb (void *cls,
396{ 375{
397 struct BobServiceSession *s = cls; 376 struct BobServiceSession *s = cls;
398 struct GNUNET_SCALARPRODUCT_Element *e = value; 377 struct GNUNET_SCALARPRODUCT_Element *e = value;
399 gcry_mpi_t mval; 378
400 int64_t val; 379 s->sorted_elements[s->used_element_count].value = (int64_t) GNUNET_ntohll (
401 380 e->value);
402 mval = gcry_mpi_new (0); 381 s->sorted_elements[s->used_element_count].key = &e->key;
403 val = (int64_t) GNUNET_ntohll (e->value);
404 if (0 > val)
405 gcry_mpi_sub_ui (mval, mval, -val);
406 else
407 gcry_mpi_add_ui (mval, mval, val);
408 s->sorted_elements [s->used_element_count].value = mval;
409 s->sorted_elements [s->used_element_count].key = &e->key;
410 s->used_element_count++; 382 s->used_element_count++;
411 return GNUNET_OK; 383 return GNUNET_OK;
412} 384}
@@ -490,13 +462,10 @@ handle_alices_cryptodata_message (void *cls,
490 const struct GNUNET_CRYPTO_EccPoint *payload; 462 const struct GNUNET_CRYPTO_EccPoint *payload;
491 uint32_t contained_elements; 463 uint32_t contained_elements;
492 unsigned int max; 464 unsigned int max;
493 unsigned int i; 465 const struct GNUNET_CRYPTO_EccPoint *g_i;
494 const struct MpiElement *b_i; 466 const struct GNUNET_CRYPTO_EccPoint *h_i;
495 gcry_mpi_point_t tmp; 467 struct GNUNET_CRYPTO_EccPoint g_i_b_i;
496 gcry_mpi_point_t g_i; 468 struct GNUNET_CRYPTO_EccPoint h_i_b_i;
497 gcry_mpi_point_t h_i;
498 gcry_mpi_point_t g_i_b_i;
499 gcry_mpi_point_t h_i_b_i;
500 469
501 contained_elements = ntohl (msg->contained_element_count); 470 contained_elements = ntohl (msg->contained_element_count);
502 max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements); 471 max = GNUNET_CONTAINER_multihashmap_size (s->intersected_elements);
@@ -522,21 +491,29 @@ handle_alices_cryptodata_message (void *cls,
522 (unsigned int) contained_elements); 491 (unsigned int) contained_elements);
523 payload = (const struct GNUNET_CRYPTO_EccPoint *) &msg[1]; 492 payload = (const struct GNUNET_CRYPTO_EccPoint *) &msg[1];
524 493
525 for (i = 0; i < contained_elements; i++) 494 for (unsigned int i = 0; i < contained_elements; i++)
526 { 495 {
527 b_i = &s->sorted_elements[i + s->cadet_received_element_count]; 496 int64_t val = s->sorted_elements[i + s->cadet_received_element_count].value;
528 g_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, 497 struct GNUNET_CRYPTO_EccScalar vali;
529 &payload[i * 2]); 498
530 g_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, 499 GNUNET_assert (INT64_MIN != val);
531 g_i, 500 GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
532 b_i->value); 501 &vali);
533 gcry_mpi_point_release (g_i); 502 if (val < 0)
534 h_i = GNUNET_CRYPTO_ecc_bin_to_point (edc, 503 crypto_core_ed25519_scalar_negate (vali.v,
535 &payload[i * 2 + 1]); 504 vali.v);
536 h_i_b_i = GNUNET_CRYPTO_ecc_pmul_mpi (edc, 505 g_i = &payload[i * 2];
537 h_i, 506 /* g_i_b_i = g_i^vali */
538 b_i->value); 507 GNUNET_assert (GNUNET_OK ==
539 gcry_mpi_point_release (h_i); 508 GNUNET_CRYPTO_ecc_pmul_mpi (g_i,
509 &vali,
510 &g_i_b_i));
511 h_i = &payload[i * 2 + 1];
512 /* h_i_b_i = h_i^vali */
513 GNUNET_assert (GNUNET_OK ==
514 GNUNET_CRYPTO_ecc_pmul_mpi (h_i,
515 &vali,
516 &h_i_b_i));
540 if (0 == i + s->cadet_received_element_count) 517 if (0 == i + s->cadet_received_element_count)
541 { 518 {
542 /* first iteration, nothing to add */ 519 /* first iteration, nothing to add */
@@ -546,18 +523,14 @@ handle_alices_cryptodata_message (void *cls,
546 else 523 else
547 { 524 {
548 /* further iterations, cummulate resulting value */ 525 /* further iterations, cummulate resulting value */
549 tmp = GNUNET_CRYPTO_ecc_add (edc, 526 GNUNET_assert (GNUNET_OK ==
550 s->prod_g_i_b_i, 527 GNUNET_CRYPTO_ecc_add (&s->prod_g_i_b_i,
551 g_i_b_i); 528 &g_i_b_i,
552 gcry_mpi_point_release (s->prod_g_i_b_i); 529 &s->prod_g_i_b_i));
553 gcry_mpi_point_release (g_i_b_i); 530 GNUNET_assert (GNUNET_OK ==
554 s->prod_g_i_b_i = tmp; 531 GNUNET_CRYPTO_ecc_add (&s->prod_h_i_b_i,
555 tmp = GNUNET_CRYPTO_ecc_add (edc, 532 &h_i_b_i,
556 s->prod_h_i_b_i, 533 &s->prod_h_i_b_i));
557 h_i_b_i);
558 gcry_mpi_point_release (s->prod_h_i_b_i);
559 gcry_mpi_point_release (h_i_b_i);
560 s->prod_h_i_b_i = tmp;
561 } 534 }
562 } 535 }
563 s->cadet_received_element_count += contained_elements; 536 s->cadet_received_element_count += contained_elements;
@@ -747,10 +720,9 @@ cb_channel_incoming (void *cls,
747 * @return #GNUNET_OK if @a msg is well-formed 720 * @return #GNUNET_OK if @a msg is well-formed
748 */ 721 */
749static int 722static int
750check_bob_client_message_multipart (void *cls, 723check_bob_client_message_multipart (
751 const struct 724 void *cls,
752 ComputationBobCryptodataMultipartMessage * 725 const struct ComputationBobCryptodataMultipartMessage *msg)
753 msg)
754{ 726{
755 struct BobServiceSession *s = cls; 727 struct BobServiceSession *s = cls;
756 uint32_t contained_count; 728 uint32_t contained_count;
@@ -781,10 +753,9 @@ check_bob_client_message_multipart (void *cls,
781 * @param msg the actual message 753 * @param msg the actual message
782 */ 754 */
783static void 755static void
784handle_bob_client_message_multipart (void *cls, 756handle_bob_client_message_multipart (
785 const struct 757 void *cls,
786 ComputationBobCryptodataMultipartMessage * 758 const struct ComputationBobCryptodataMultipartMessage *msg)
787 msg)
788{ 759{
789 struct BobServiceSession *s = cls; 760 struct BobServiceSession *s = cls;
790 uint32_t contained_count; 761 uint32_t contained_count;
diff --git a/src/scalarproduct/perf_scalarproduct.sh b/src/scalarproduct/perf_scalarproduct.sh
index a7935873e..b15465c9a 100755
--- a/src/scalarproduct/perf_scalarproduct.sh
+++ b/src/scalarproduct/perf_scalarproduct.sh
@@ -1,7 +1,7 @@
1#!/bin/bash 1#!/bin/bash
2# Computes a simple scalar product, with configurable vector size. 2# Computes a simple scalar product, with configurable vector size.
3# 3#
4# Some results (wall-clock for Alice+Bob, single-core, i7): 4# Some results (wall-clock for Alice+Bob, single-core, i7, libgcrypt):
5# SIZE 2048-H(s) 2048-O(s) 1024-O(s) ECC-2^20-H(s) ECC-2^28-H(s) 5# SIZE 2048-H(s) 2048-O(s) 1024-O(s) ECC-2^20-H(s) ECC-2^28-H(s)
6# 25 10 14 3 2 29 6# 25 10 14 3 2 29
7# 50 17 21 5 2 29 7# 50 17 21 5 2 29
@@ -11,8 +11,21 @@
11# 800 304 32 OOR 33 11# 800 304 32 OOR 33
12 12
13# Bandwidth (including set intersection): 13# Bandwidth (including set intersection):
14# RSA-2048 ECC 14# RSA-1024 RSA-2048 ECC
15# 800: 3846 kb 70 kb 15# 800: 629 kb 1234 kb 65 kb
16#
17# LIBSODIUM, AMD Threadripper 1950:
18#
19# SIZE 2048-O(s) 1024-O(s) ECC-2^20-H(s) ECC-2^28-H(s)
20# 25 4.3 0.7 0.129 4.233
21# 50 7.7 1.2 0.143 4.267
22# 100 10.3 2.4 0.163 4.282
23# 200 19.8 3.0 0.192 4.326
24# 400 35.9 6.0 0.253 4.358
25# 800 73.7 12.6 0.379 4.533
26
27#
28#
16# Configure benchmark size: 29# Configure benchmark size:
17SIZE=800 30SIZE=800
18# 31#
diff --git a/src/scalarproduct/scalarproduct_api.c b/src/scalarproduct/scalarproduct_api.c
index b2a90c222..4ac39614a 100644
--- a/src/scalarproduct/scalarproduct_api.c
+++ b/src/scalarproduct/scalarproduct_api.c
@@ -42,14 +42,10 @@
42 * @param status processing status code 42 * @param status processing status code
43 */ 43 */
44typedef void 44typedef void
45(*GNUNET_SCALARPRODUCT_ResponseMessageHandler) (struct 45(*GNUNET_SCALARPRODUCT_ResponseMessageHandler) (
46 GNUNET_SCALARPRODUCT_ComputationHandle 46 struct GNUNET_SCALARPRODUCT_ComputationHandle *h,
47 *h, 47 const struct ClientResponseMessage *msg,
48 const struct 48 enum GNUNET_SCALARPRODUCT_ResponseStatus status);
49 ClientResponseMessage *msg,
50 enum
51 GNUNET_SCALARPRODUCT_ResponseStatus
52 status);
53 49
54 50
55/** 51/**
@@ -172,13 +168,12 @@ check_unique (const struct GNUNET_SCALARPRODUCT_Element *elements,
172 uint32_t element_count) 168 uint32_t element_count)
173{ 169{
174 struct GNUNET_CONTAINER_MultiHashMap *map; 170 struct GNUNET_CONTAINER_MultiHashMap *map;
175 uint32_t i;
176 int ok; 171 int ok;
177 172
178 ok = GNUNET_OK; 173 ok = GNUNET_OK;
179 map = GNUNET_CONTAINER_multihashmap_create (2 * element_count, 174 map = GNUNET_CONTAINER_multihashmap_create (2 * element_count,
180 GNUNET_YES); 175 GNUNET_YES);
181 for (i = 0; i < element_count; i++) 176 for (uint32_t i = 0; i < element_count; i++)
182 if (GNUNET_OK != 177 if (GNUNET_OK !=
183 GNUNET_CONTAINER_multihashmap_put (map, 178 GNUNET_CONTAINER_multihashmap_put (map,
184 &elements[i].key, 179 &elements[i].key,
@@ -227,16 +222,13 @@ mq_error_handler (void *cls,
227 * @return a new handle for this computation 222 * @return a new handle for this computation
228 */ 223 */
229struct GNUNET_SCALARPRODUCT_ComputationHandle * 224struct GNUNET_SCALARPRODUCT_ComputationHandle *
230GNUNET_SCALARPRODUCT_accept_computation (const struct 225GNUNET_SCALARPRODUCT_accept_computation (
231 GNUNET_CONFIGURATION_Handle *cfg, 226 const struct GNUNET_CONFIGURATION_Handle *cfg,
232 const struct 227 const struct GNUNET_HashCode *session_key,
233 GNUNET_HashCode *session_key, 228 const struct GNUNET_SCALARPRODUCT_Element *elements,
234 const struct 229 uint32_t element_count,
235 GNUNET_SCALARPRODUCT_Element *elements, 230 GNUNET_SCALARPRODUCT_ContinuationWithStatus cont,
236 uint32_t element_count, 231 void *cont_cls)
237 GNUNET_SCALARPRODUCT_ContinuationWithStatus
238 cont,
239 void *cont_cls)
240{ 232{
241 struct GNUNET_SCALARPRODUCT_ComputationHandle *h 233 struct GNUNET_SCALARPRODUCT_ComputationHandle *h
242 = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle); 234 = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle);
@@ -389,16 +381,14 @@ process_result_message (struct GNUNET_SCALARPRODUCT_ComputationHandle *h,
389 * @return a new handle for this computation 381 * @return a new handle for this computation
390 */ 382 */
391struct GNUNET_SCALARPRODUCT_ComputationHandle * 383struct GNUNET_SCALARPRODUCT_ComputationHandle *
392GNUNET_SCALARPRODUCT_start_computation (const struct 384GNUNET_SCALARPRODUCT_start_computation (
393 GNUNET_CONFIGURATION_Handle *cfg, 385 const struct GNUNET_CONFIGURATION_Handle *cfg,
394 const struct 386 const struct GNUNET_HashCode *session_key,
395 GNUNET_HashCode *session_key, 387 const struct GNUNET_PeerIdentity *peer,
396 const struct GNUNET_PeerIdentity *peer, 388 const struct GNUNET_SCALARPRODUCT_Element *elements,
397 const struct 389 uint32_t element_count,
398 GNUNET_SCALARPRODUCT_Element *elements, 390 GNUNET_SCALARPRODUCT_DatumProcessor cont,
399 uint32_t element_count, 391 void *cont_cls)
400 GNUNET_SCALARPRODUCT_DatumProcessor cont,
401 void *cont_cls)
402{ 392{
403 struct GNUNET_SCALARPRODUCT_ComputationHandle *h 393 struct GNUNET_SCALARPRODUCT_ComputationHandle *h
404 = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle); 394 = GNUNET_new (struct GNUNET_SCALARPRODUCT_ComputationHandle);
diff --git a/src/scalarproduct/test_ecc_scalarproduct.c b/src/scalarproduct/test_ecc_scalarproduct.c
index eced3ef6a..85460cb05 100644
--- a/src/scalarproduct/test_ecc_scalarproduct.c
+++ b/src/scalarproduct/test_ecc_scalarproduct.c
@@ -45,20 +45,12 @@ test_sp (const unsigned int *avec,
45 const unsigned int *bvec) 45 const unsigned int *bvec)
46{ 46{
47 unsigned int len; 47 unsigned int len;
48 unsigned int i; 48 struct GNUNET_CRYPTO_EccScalar a;
49 gcry_mpi_t a; 49 struct GNUNET_CRYPTO_EccScalar a_neg;
50 gcry_mpi_t a_inv; 50 struct GNUNET_CRYPTO_EccPoint *g;
51 gcry_mpi_t ri; 51 struct GNUNET_CRYPTO_EccPoint *h;
52 gcry_mpi_t val; 52 struct GNUNET_CRYPTO_EccPoint pg;
53 gcry_mpi_t ria; 53 struct GNUNET_CRYPTO_EccPoint ph;
54 gcry_mpi_t tmp;
55 gcry_mpi_point_t *g;
56 gcry_mpi_point_t *h;
57 gcry_mpi_point_t pg;
58 gcry_mpi_point_t ph;
59 gcry_mpi_point_t pgi;
60 gcry_mpi_point_t gsp;
61 int sp;
62 54
63 /* determine length */ 55 /* determine length */
64 for (len = 0; 0 != avec[len]; len++) 56 for (len = 0; 0 != avec[len]; len++)
@@ -67,90 +59,133 @@ test_sp (const unsigned int *avec,
67 return 0; 59 return 0;
68 60
69 /* Alice */ 61 /* Alice */
70 GNUNET_CRYPTO_ecc_rnd_mpi (edc, 62 GNUNET_CRYPTO_ecc_rnd_mpi (&a,
71 &a, &a_inv); 63 &a_neg);
72 g = GNUNET_new_array (len, 64 g = GNUNET_new_array (len,
73 gcry_mpi_point_t); 65 struct GNUNET_CRYPTO_EccPoint);
74 h = GNUNET_new_array (len, 66 h = GNUNET_new_array (len,
75 gcry_mpi_point_t); 67 struct GNUNET_CRYPTO_EccPoint);
76 ria = gcry_mpi_new (0); 68 for (unsigned int i = 0; i < len; i++)
77 tmp = gcry_mpi_new (0);
78 for (i = 0; i < len; i++)
79 { 69 {
80 ri = GNUNET_CRYPTO_ecc_random_mod_n (edc); 70 struct GNUNET_CRYPTO_EccScalar tmp;
81 g[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc, 71 struct GNUNET_CRYPTO_EccScalar ri;
82 ri); 72 struct GNUNET_CRYPTO_EccScalar ria;
83 /* ria = ri * a */ 73
84 gcry_mpi_mul (ria, 74 GNUNET_CRYPTO_ecc_random_mod_n (&ri);
85 ri, 75 GNUNET_assert (GNUNET_OK ==
86 a); 76 GNUNET_CRYPTO_ecc_dexp_mpi (&ri,
77 &g[i]));
78 /* ria = ri * a mod L, where L is the order of the main subgroup */
79 crypto_core_ed25519_scalar_mul (ria.v,
80 ri.v,
81 a.v);
87 /* tmp = ria + avec[i] */ 82 /* tmp = ria + avec[i] */
88 gcry_mpi_add_ui (tmp, 83 {
89 ria, 84 int64_t val = avec[i];
90 avec[i]); 85 struct GNUNET_CRYPTO_EccScalar vali;
91 h[i] = GNUNET_CRYPTO_ecc_dexp_mpi (edc, 86
92 tmp); 87 GNUNET_assert (INT64_MIN != val);
88 GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
89 &vali);
90 if (val > 0)
91 crypto_core_ed25519_scalar_add (tmp.v,
92 ria.v,
93 vali.v);
94 else
95 crypto_core_ed25519_scalar_sub (tmp.v,
96 ria.v,
97 vali.v);
98 }
99 /* h[i] = g^tmp = g^{ria + avec[i]} */
100 GNUNET_assert (GNUNET_OK ==
101 GNUNET_CRYPTO_ecc_dexp_mpi (&tmp,
102 &h[i]));
93 } 103 }
94 gcry_mpi_release (ria);
95 gcry_mpi_release (tmp);
96 104
97 /* Bob */ 105 /* Bob */
98 val = gcry_mpi_new (0); 106 for (unsigned int i = 0; i < len; i++)
99 gcry_mpi_set_ui (val, bvec[0]);
100 pg = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
101 g[0],
102 val);
103 ph = GNUNET_CRYPTO_ecc_pmul_mpi (edc,
104 h[0],
105 val);
106 for (i = 1; i < len; i++)
107 { 107 {
108 gcry_mpi_point_t m; 108 struct GNUNET_CRYPTO_EccPoint gm;
109 gcry_mpi_point_t tmp; 109 struct GNUNET_CRYPTO_EccPoint hm;
110 110
111 gcry_mpi_set_ui (val, bvec[i]); 111 {
112 m = GNUNET_CRYPTO_ecc_pmul_mpi (edc, 112 int64_t val = bvec[i];
113 g[i], 113 struct GNUNET_CRYPTO_EccScalar vali;
114 val); 114
115 tmp = GNUNET_CRYPTO_ecc_add (edc, 115 GNUNET_assert (INT64_MIN != val);
116 m, 116 GNUNET_CRYPTO_ecc_scalar_from_int (val > 0 ? val : -val,
117 pg); 117 &vali);
118 gcry_mpi_point_release (m); 118 if (val < 0)
119 gcry_mpi_point_release (pg); 119 crypto_core_ed25519_scalar_negate (vali.v,
120 gcry_mpi_point_release (g[i]); 120 vali.v);
121 pg = tmp; 121 /* gm = g[i]^vali */
122 122 GNUNET_assert (GNUNET_OK ==
123 m = GNUNET_CRYPTO_ecc_pmul_mpi (edc, 123 GNUNET_CRYPTO_ecc_pmul_mpi (&g[i],
124 h[i], 124 &vali,
125 val); 125 &gm));
126 tmp = GNUNET_CRYPTO_ecc_add (edc, 126 /* hm = h[i]^vali */
127 m, 127 GNUNET_assert (GNUNET_OK ==
128 ph); 128 GNUNET_CRYPTO_ecc_pmul_mpi (&h[i],
129 gcry_mpi_point_release (m); 129 &vali,
130 gcry_mpi_point_release (ph); 130 &hm));
131 gcry_mpi_point_release (h[i]); 131 }
132 ph = tmp; 132 if (0 != i)
133 {
134 /* pg += gm */
135 GNUNET_assert (GNUNET_OK ==
136 GNUNET_CRYPTO_ecc_add (&gm,
137 &pg,
138 &pg));
139 /* ph += hm */
140 GNUNET_assert (GNUNET_OK ==
141 GNUNET_CRYPTO_ecc_add (&hm,
142 &ph,
143 &ph));
144 }
145 else
146 {
147 pg = gm;
148 ph = hm;
149 }
133 } 150 }
134 gcry_mpi_release (val);
135 GNUNET_free (g); 151 GNUNET_free (g);
136 GNUNET_free (h); 152 GNUNET_free (h);
137 153
138 /* Alice */ 154 /* Alice */
139 pgi = GNUNET_CRYPTO_ecc_pmul_mpi (edc, 155 {
140 pg, 156 struct GNUNET_CRYPTO_EccPoint pgi;
141 a_inv); 157 struct GNUNET_CRYPTO_EccPoint gsp;
142 gsp = GNUNET_CRYPTO_ecc_add (edc, 158
143 pgi, 159 /* pgi = pg^inv */
144 ph); 160 GNUNET_assert (GNUNET_OK ==
145 gcry_mpi_point_release (pgi); 161 GNUNET_CRYPTO_ecc_pmul_mpi (&pg,
146 gcry_mpi_point_release (ph); 162 &a_neg,
147 sp = GNUNET_CRYPTO_ecc_dlog (edc, 163 &pgi));
148 gsp); 164 /* gsp = pgi + ph */
149 gcry_mpi_point_release (gsp); 165 GNUNET_assert (GNUNET_OK ==
150 return sp; 166 GNUNET_CRYPTO_ecc_add (&pgi,
167 &ph,
168 &gsp));
169 return GNUNET_CRYPTO_ecc_dlog (edc,
170 &gsp);
171 }
151} 172}
152 173
153 174
175/**
176 * Macro that checks that @a want is equal to @a have and
177 * if not returns with a failure code.
178 */
179#define CHECK(want,have) do { \
180 if (want != have) { \
181 GNUNET_break (0); \
182 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, \
183 "Wanted %d, got %d\n", want, have); \
184 GNUNET_CRYPTO_ecc_dlog_release (edc); \
185 return 1; \
186 } } while (0)
187
188
154int 189int
155main (int argc, char *argv[]) 190main (int argc, char *argv[])
156{ 191{
@@ -163,12 +198,12 @@ main (int argc, char *argv[])
163 "WARNING", 198 "WARNING",
164 NULL); 199 NULL);
165 edc = GNUNET_CRYPTO_ecc_dlog_prepare (128, 128); 200 edc = GNUNET_CRYPTO_ecc_dlog_prepare (128, 128);
166 GNUNET_assert (2 == test_sp (v11, v11)); 201 CHECK (2, test_sp (v11, v11));
167 GNUNET_assert (4 == test_sp (v22, v11)); 202 CHECK (4, test_sp (v22, v11));
168 GNUNET_assert (8 == test_sp (v35, v11)); 203 CHECK (8, test_sp (v35, v11));
169 GNUNET_assert (26 == test_sp (v35, v24)); 204 CHECK (26, test_sp (v35, v24));
170 GNUNET_assert (26 == test_sp (v24, v35)); 205 CHECK (26, test_sp (v24, v35));
171 GNUNET_assert (16 == test_sp (v22, v35)); 206 CHECK (16, test_sp (v22, v35));
172 GNUNET_CRYPTO_ecc_dlog_release (edc); 207 GNUNET_CRYPTO_ecc_dlog_release (edc);
173 return 0; 208 return 0;
174} 209}
diff --git a/src/scalarproduct/test_scalarproduct_negative.sh b/src/scalarproduct/test_scalarproduct_negative.sh
index b08e4527f..459406836 100755
--- a/src/scalarproduct/test_scalarproduct_negative.sh
+++ b/src/scalarproduct/test_scalarproduct_negative.sh
@@ -5,6 +5,9 @@ INPUTALICE="-k CCC -e 'AB,10;RO,-3;FL,-3;LOL,1;'"
5INPUTBOB="-k CCC -e 'BC,-20000;RO,1000;FL,100;LOL,24;'" 5INPUTBOB="-k CCC -e 'BC,-20000;RO,1000;FL,100;LOL,24;'"
6 6
7# necessary to make the testing prefix deterministic, so we can access the config files 7# necessary to make the testing prefix deterministic, so we can access the config files
8unset XDG_DATA_HOME
9unset XDG_CONFIG_HOME
10
8PREFIX=/tmp/test-scalarproduct`date +%H%M%S` 11PREFIX=/tmp/test-scalarproduct`date +%H%M%S`
9 12
10# where can we find the peers config files? 13# where can we find the peers config files?
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index e2614e5e3..f05fc7bf7 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -460,6 +460,7 @@ if HAVE_NOLIBGCRYPT19
460test_crypto_ecc_dlog_SOURCES = \ 460test_crypto_ecc_dlog_SOURCES = \
461 test_crypto_ecc_dlog.c 461 test_crypto_ecc_dlog.c
462test_crypto_ecc_dlog_LDADD = \ 462test_crypto_ecc_dlog_LDADD = \
463 -lsodium \
463 libgnunetutil.la \ 464 libgnunetutil.la \
464 $(LIBGCRYPT_LIBS) 465 $(LIBGCRYPT_LIBS)
465endif 466endif
@@ -610,7 +611,7 @@ perf_crypto_ecc_dlog_SOURCES = \
610 perf_crypto_ecc_dlog.c 611 perf_crypto_ecc_dlog.c
611perf_crypto_ecc_dlog_LDADD = \ 612perf_crypto_ecc_dlog_LDADD = \
612 libgnunetutil.la \ 613 libgnunetutil.la \
613 -lgcrypt 614 -lsodium
614endif 615endif
615 616
616perf_crypto_rsa_SOURCES = \ 617perf_crypto_rsa_SOURCES = \
diff --git a/src/util/crypto_ecc_dlog.c b/src/util/crypto_ecc_dlog.c
index 408d64e58..916acd9dd 100644
--- a/src/util/crypto_ecc_dlog.c
+++ b/src/util/crypto_ecc_dlog.c
@@ -32,35 +32,6 @@
32 32
33 33
34/** 34/**
35 * 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
37 * changes that break stuff badly. The name of the curve given here
38 * must be agreed by all peers and be supported by libgcrypt.
39 */
40#define CURVE "Ed25519"
41
42
43/**
44 *
45 */
46static void
47extract_pk (gcry_mpi_point_t pt,
48 gcry_ctx_t ctx,
49 struct GNUNET_PeerIdentity *pid)
50{
51 gcry_mpi_t q_y;
52
53 GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", pt, ctx));
54 q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
55 GNUNET_assert (q_y);
56 GNUNET_CRYPTO_mpi_print_unsigned (pid->public_key.q_y,
57 sizeof(pid->public_key.q_y),
58 q_y);
59 gcry_mpi_release (q_y);
60}
61
62
63/**
64 * Internal structure used to cache pre-calculated values for DLOG calculation. 35 * Internal structure used to cache pre-calculated values for DLOG calculation.
65 */ 36 */
66struct GNUNET_CRYPTO_EccDlogContext 37struct GNUNET_CRYPTO_EccDlogContext
@@ -90,160 +61,105 @@ struct GNUNET_CRYPTO_EccDlogContext
90}; 61};
91 62
92 63
93/**
94 * Convert point value to binary representation.
95 *
96 * @param edc calculation context for ECC operations
97 * @param point computational point representation
98 * @param[out] bin binary point representation
99 */
100void
101GNUNET_CRYPTO_ecc_point_to_bin (struct GNUNET_CRYPTO_EccDlogContext *edc,
102 gcry_mpi_point_t point,
103 struct GNUNET_CRYPTO_EccPoint *bin)
104{
105 gcry_mpi_t q_y;
106
107 GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", point, edc->ctx));
108 q_y = gcry_mpi_ec_get_mpi ("q@eddsa", edc->ctx, 0);
109 GNUNET_assert (q_y);
110 GNUNET_CRYPTO_mpi_print_unsigned (bin->q_y,
111 sizeof(bin->q_y),
112 q_y);
113 gcry_mpi_release (q_y);
114}
115
116
117/**
118 * Convert binary representation of a point to computational representation.
119 *
120 * @param edc calculation context for ECC operations
121 * @param bin binary point representation
122 * @return computational representation
123 */
124gcry_mpi_point_t
125GNUNET_CRYPTO_ecc_bin_to_point (struct GNUNET_CRYPTO_EccDlogContext *edc,
126 const struct GNUNET_CRYPTO_EccPoint *bin)
127{
128 gcry_sexp_t pub_sexpr;
129 gcry_ctx_t ctx;
130 gcry_mpi_point_t q;
131
132 (void) edc;
133 if (0 != gcry_sexp_build (&pub_sexpr, NULL,
134 "(public-key(ecc(curve " CURVE ")(q %b)))",
135 (int) sizeof(bin->q_y),
136 bin->q_y))
137 {
138 GNUNET_break (0);
139 return NULL;
140 }
141 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
142 gcry_sexp_release (pub_sexpr);
143 q = gcry_mpi_ec_get_point ("q", ctx, 0);
144 gcry_ctx_release (ctx);
145 return q;
146}
147
148
149/**
150 * Do pre-calculation for ECC discrete logarithm for small factors.
151 *
152 * @param max maximum value the factor can be
153 * @param mem memory to use (should be smaller than @a max), must not be zero.
154 * @return NULL on error
155 */
156struct GNUNET_CRYPTO_EccDlogContext * 64struct GNUNET_CRYPTO_EccDlogContext *
157GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, 65GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max,
158 unsigned int mem) 66 unsigned int mem)
159{ 67{
160 struct GNUNET_CRYPTO_EccDlogContext *edc; 68 struct GNUNET_CRYPTO_EccDlogContext *edc;
161 unsigned int K = ((max + (mem - 1)) / mem); 69 int K = ((max + (mem - 1)) / mem);
162 gcry_mpi_point_t g;
163 struct GNUNET_PeerIdentity key;
164 gcry_mpi_point_t gKi;
165 gcry_mpi_t fact;
166 gcry_mpi_t n;
167 unsigned int i;
168 70
169 GNUNET_assert (max < INT32_MAX); 71 GNUNET_assert (max < INT32_MAX);
170 edc = GNUNET_new (struct GNUNET_CRYPTO_EccDlogContext); 72 edc = GNUNET_new (struct GNUNET_CRYPTO_EccDlogContext);
171 edc->max = max; 73 edc->max = max;
172 edc->mem = mem; 74 edc->mem = mem;
173
174 edc->map = GNUNET_CONTAINER_multipeermap_create (mem * 2, 75 edc->map = GNUNET_CONTAINER_multipeermap_create (mem * 2,
175 GNUNET_NO); 76 GNUNET_NO);
176 77 for (int i = -(int) mem; i <= (int) mem; i++)
177 GNUNET_assert (0 == gcry_mpi_ec_new (&edc->ctx,
178 NULL,
179 CURVE));
180 g = gcry_mpi_ec_get_point ("g", edc->ctx, 0);
181 GNUNET_assert (NULL != g);
182 fact = gcry_mpi_new (0);
183 gKi = gcry_mpi_point_new (0);
184 for (i = 0; i <= mem; i++)
185 { 78 {
186 gcry_mpi_set_ui (fact, i * K); 79 struct GNUNET_CRYPTO_EccScalar Ki;
187 gcry_mpi_ec_mul (gKi, fact, g, edc->ctx); 80 struct GNUNET_PeerIdentity key;
188 extract_pk (gKi, edc->ctx, &key); 81
82 GNUNET_CRYPTO_ecc_scalar_from_int (K * i,
83 &Ki);
84 if (0 == i) /* libsodium does not like to multiply with zero */
85 GNUNET_assert (
86 0 ==
87 crypto_core_ed25519_sub ((unsigned char *) &key,
88 (unsigned char *) &key,
89 (unsigned char *) &key));
90 else
91 GNUNET_assert (
92 0 ==
93 crypto_scalarmult_ed25519_base_noclamp ((unsigned char*) &key,
94 Ki.v));
95 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
96 "K*i: %d (mem=%u, i=%d) => %s\n",
97 K * i,
98 mem,
99 i,
100 GNUNET_i2s (&key));
189 GNUNET_assert (GNUNET_OK == 101 GNUNET_assert (GNUNET_OK ==
190 GNUNET_CONTAINER_multipeermap_put (edc->map, 102 GNUNET_CONTAINER_multipeermap_put (edc->map,
191 &key, 103 &key,
192 (void *) (long) i + max, 104 (void *) (long) i + max,
193 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 105 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
194 } 106 }
195 /* negative values */
196 n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
197 for (i = 1; i < mem; i++)
198 {
199 gcry_mpi_set_ui (fact, i * K);
200 gcry_mpi_sub (fact, n, fact);
201 gcry_mpi_ec_mul (gKi, fact, g, edc->ctx);
202 extract_pk (gKi, edc->ctx, &key);
203 GNUNET_assert (GNUNET_OK ==
204 GNUNET_CONTAINER_multipeermap_put (edc->map,
205 &key,
206 (void *) (long) max - i,
207 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
208 }
209 gcry_mpi_release (fact);
210 gcry_mpi_release (n);
211 gcry_mpi_point_release (gKi);
212 gcry_mpi_point_release (g);
213 return edc; 107 return edc;
214} 108}
215 109
216 110
217/**
218 * Calculate ECC discrete logarithm for small factors.
219 *
220 * @param edc precalculated values, determine range of factors
221 * @param input point on the curve to factor
222 * @return INT_MAX if dlog failed, otherwise the factor
223 */
224int 111int
225GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, 112GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
226 gcry_mpi_point_t input) 113 const struct GNUNET_CRYPTO_EccPoint *input)
227{ 114{
228 unsigned int K = ((edc->max + (edc->mem - 1)) / edc->mem); 115 unsigned int K = ((edc->max + (edc->mem - 1)) / edc->mem);
229 gcry_mpi_point_t g;
230 struct GNUNET_PeerIdentity key;
231 gcry_mpi_point_t q;
232 unsigned int i;
233 int res; 116 int res;
234 void *retp; 117 struct GNUNET_CRYPTO_EccPoint g;
235 118 struct GNUNET_CRYPTO_EccPoint q;
236 g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); 119 struct GNUNET_CRYPTO_EccPoint nq;
237 GNUNET_assert (NULL != g);
238 q = gcry_mpi_point_new (0);
239 120
121 {
122 struct GNUNET_CRYPTO_EccScalar fact;
123
124 memset (&fact,
125 0,
126 sizeof (fact));
127 sodium_increment (fact.v,
128 sizeof (fact.v));
129 GNUNET_assert (0 ==
130 crypto_scalarmult_ed25519_base_noclamp (g.v,
131 fact.v));
132 }
133 /* make compiler happy: initialize q and nq, technically not needed! */
134 memset (&q,
135 0,
136 sizeof (q));
137 memset (&nq,
138 0,
139 sizeof (nq));
240 res = INT_MAX; 140 res = INT_MAX;
241 for (i = 0; i <= edc->max / edc->mem; i++) 141 for (unsigned int i = 0; i <= edc->max / edc->mem; i++)
242 { 142 {
143 struct GNUNET_PeerIdentity key;
144 void *retp;
145
146 GNUNET_assert (sizeof (key) == crypto_scalarmult_BYTES);
243 if (0 == i) 147 if (0 == i)
244 extract_pk (input, edc->ctx, &key); 148 {
149 memcpy (&key,
150 input,
151 sizeof (key));
152 }
245 else 153 else
246 extract_pk (q, edc->ctx, &key); 154 {
155 memcpy (&key,
156 &q,
157 sizeof (key));
158 }
159 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
160 "Trying offset i=%u): %s\n",
161 i,
162 GNUNET_i2s (&key));
247 retp = GNUNET_CONTAINER_multipeermap_get (edc->map, 163 retp = GNUNET_CONTAINER_multipeermap_get (edc->map,
248 &key); 164 &key);
249 if (NULL != retp) 165 if (NULL != retp)
@@ -257,248 +173,163 @@ GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
257 break; 173 break;
258 /* q = q + g */ 174 /* q = q + g */
259 if (0 == i) 175 if (0 == i)
260 gcry_mpi_ec_add (q, input, g, edc->ctx); 176 {
177 GNUNET_assert (0 ==
178 crypto_core_ed25519_add (q.v,
179 input->v,
180 g.v));
181 }
261 else 182 else
262 gcry_mpi_ec_add (q, q, g, edc->ctx); 183 {
184 GNUNET_assert (0 ==
185 crypto_core_ed25519_add (q.v,
186 q.v,
187 g.v));
188 }
263 } 189 }
264 gcry_mpi_point_release (g);
265 gcry_mpi_point_release (q);
266
267 return res; 190 return res;
268} 191}
269 192
270 193
271/** 194void
272 * Generate a random value mod n. 195GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccScalar *r)
273 *
274 * @param edc ECC context
275 * @return random value mod n.
276 */
277gcry_mpi_t
278GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc)
279{ 196{
280 gcry_mpi_t n; 197 crypto_core_ed25519_scalar_random (r->v);
281 unsigned int highbit;
282 gcry_mpi_t r;
283
284 n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
285
286 /* check public key for number of bits, bail out if key is all zeros */
287 highbit = 256; /* Curve25519 */
288 while ((! gcry_mpi_test_bit (n, highbit)) &&
289 (0 != highbit))
290 highbit--;
291 GNUNET_assert (0 != highbit);
292 /* generate fact < n (without bias) */
293 GNUNET_assert (NULL != (r = gcry_mpi_new (0)));
294 do
295 {
296 gcry_mpi_randomize (r,
297 highbit + 1,
298 GCRY_STRONG_RANDOM);
299 }
300 while (gcry_mpi_cmp (r, n) >= 0);
301 gcry_mpi_release (n);
302 return r;
303} 198}
304 199
305 200
306/**
307 * Release precalculated values.
308 *
309 * @param edc dlog context
310 */
311void 201void
312GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *edc) 202GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *edc)
313{ 203{
314 gcry_ctx_release (edc->ctx);
315 GNUNET_CONTAINER_multipeermap_destroy (edc->map); 204 GNUNET_CONTAINER_multipeermap_destroy (edc->map);
316 GNUNET_free (edc); 205 GNUNET_free (edc);
317} 206}
318 207
319 208
320/** 209void
321 * Multiply the generator g of the elliptic curve by @a val 210GNUNET_CRYPTO_ecc_dexp (int val,
322 * to obtain the point on the curve representing @a val. 211 struct GNUNET_CRYPTO_EccPoint *r)
323 * Afterwards, point addition will correspond to integer
324 * addition. #GNUNET_CRYPTO_ecc_dlog() can be used to
325 * convert a point back to an integer (as long as the
326 * integer is smaller than the MAX of the @a edc context).
327 *
328 * @param edc calculation context for ECC operations
329 * @param val value to encode into a point
330 * @return representation of the value as an ECC point,
331 * must be freed using #GNUNET_CRYPTO_ecc_free()
332 */
333gcry_mpi_point_t
334GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc,
335 int val)
336{ 212{
337 gcry_mpi_t fact; 213 struct GNUNET_CRYPTO_EccScalar fact;
338 gcry_mpi_t n; 214
339 gcry_mpi_point_t g; 215 GNUNET_CRYPTO_ecc_scalar_from_int (val,
340 gcry_mpi_point_t r; 216 &fact);
341 217 crypto_scalarmult_ed25519_base_noclamp (r->v,
342 g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); 218 fact.v);
343 GNUNET_assert (NULL != g);
344 fact = gcry_mpi_new (0);
345 if (val < 0)
346 {
347 n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
348 gcry_mpi_set_ui (fact, -val);
349 gcry_mpi_sub (fact, n, fact);
350 gcry_mpi_release (n);
351 }
352 else
353 {
354 gcry_mpi_set_ui (fact, val);
355 }
356 r = gcry_mpi_point_new (0);
357 gcry_mpi_ec_mul (r, fact, g, edc->ctx);
358 gcry_mpi_release (fact);
359 gcry_mpi_point_release (g);
360 return r;
361} 219}
362 220
363 221
364/** 222enum GNUNET_GenericReturnValue
365 * Multiply the generator g of the elliptic curve by @a val 223GNUNET_CRYPTO_ecc_dexp_mpi (const struct GNUNET_CRYPTO_EccScalar *val,
366 * to obtain the point on the curve representing @a val. 224 struct GNUNET_CRYPTO_EccPoint *r)
367 *
368 * @param edc calculation context for ECC operations
369 * @param val (positive) value to encode into a point
370 * @return representation of the value as an ECC point,
371 * must be freed using #GNUNET_CRYPTO_ecc_free()
372 */
373gcry_mpi_point_t
374GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
375 gcry_mpi_t val)
376{ 225{
377 gcry_mpi_point_t g; 226 if (0 ==
378 gcry_mpi_point_t r; 227 crypto_scalarmult_ed25519_base_noclamp (r->v,
379 228 val->v))
380 g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); 229 return GNUNET_OK;
381 GNUNET_assert (NULL != g); 230 return GNUNET_SYSERR;
382 r = gcry_mpi_point_new (0);
383 gcry_mpi_ec_mul (r, val, g, edc->ctx);
384 gcry_mpi_point_release (g);
385 return r;
386} 231}
387 232
388 233
389/** 234enum GNUNET_GenericReturnValue
390 * Add two points on the elliptic curve. 235GNUNET_CRYPTO_ecc_add (const struct GNUNET_CRYPTO_EccPoint *a,
391 * 236 const struct GNUNET_CRYPTO_EccPoint *b,
392 * @param edc calculation context for ECC operations 237 struct GNUNET_CRYPTO_EccPoint *r)
393 * @param a some value
394 * @param b some value
395 * @return @a a + @a b, must be freed using #GNUNET_CRYPTO_ecc_free()
396 */
397gcry_mpi_point_t
398GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc,
399 gcry_mpi_point_t a,
400 gcry_mpi_point_t b)
401{ 238{
402 gcry_mpi_point_t r; 239 if (0 ==
403 240 crypto_core_ed25519_add (r->v,
404 r = gcry_mpi_point_new (0); 241 a->v,
405 gcry_mpi_ec_add (r, a, b, edc->ctx); 242 b->v))
406 return r; 243 return GNUNET_OK;
244 return GNUNET_SYSERR;
407} 245}
408 246
409 247
410/** 248enum GNUNET_GenericReturnValue
411 * Multiply the point @a p on the elliptic curve by @a val. 249GNUNET_CRYPTO_ecc_pmul_mpi (const struct GNUNET_CRYPTO_EccPoint *p,
412 * 250 const struct GNUNET_CRYPTO_EccScalar *val,
413 * @param edc calculation context for ECC operations 251 struct GNUNET_CRYPTO_EccPoint *r)
414 * @param p point to multiply
415 * @param val (positive) value to encode into a point
416 * @return representation of the value as an ECC point,
417 * must be freed using #GNUNET_CRYPTO_ecc_free()
418 */
419gcry_mpi_point_t
420GNUNET_CRYPTO_ecc_pmul_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc,
421 gcry_mpi_point_t p,
422 gcry_mpi_t val)
423{ 252{
424 gcry_mpi_point_t r; 253 if (0 ==
425 254 crypto_scalarmult_ed25519_noclamp (r->v,
426 r = gcry_mpi_point_new (0); 255 val->v,
427 gcry_mpi_ec_mul (r, val, p, edc->ctx); 256 p->v))
428 return r; 257 return GNUNET_OK;
258 return GNUNET_SYSERR;
429} 259}
430 260
431 261
432/** 262enum GNUNET_GenericReturnValue
433 * Obtain a random point on the curve and its 263GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccPoint *r,
434 * additive inverse. Both returned values 264 struct GNUNET_CRYPTO_EccPoint *r_inv)
435 * must be freed using #GNUNET_CRYPTO_ecc_free().
436 *
437 * @param edc calculation context for ECC operations
438 * @param[out] r set to a random point on the curve
439 * @param[out] r_inv set to the additive inverse of @a r
440 */
441void
442GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccDlogContext *edc,
443 gcry_mpi_point_t *r,
444 gcry_mpi_point_t *r_inv)
445{ 265{
446 gcry_mpi_t fact; 266 struct GNUNET_CRYPTO_EccScalar s;
447 gcry_mpi_t n; 267 unsigned char inv_s[crypto_scalarmult_ed25519_SCALARBYTES];
448 gcry_mpi_point_t g; 268
449 269 GNUNET_CRYPTO_ecc_random_mod_n (&s);
450 fact = GNUNET_CRYPTO_ecc_random_mod_n (edc); 270 if (0 !=
451 271 crypto_scalarmult_ed25519_base_noclamp (r->v,
452 /* calculate 'r' */ 272 s.v))
453 g = gcry_mpi_ec_get_point ("g", edc->ctx, 0); 273 return GNUNET_SYSERR;
454 GNUNET_assert (NULL != g); 274 crypto_core_ed25519_scalar_negate (inv_s,
455 *r = gcry_mpi_point_new (0); 275 s.v);
456 gcry_mpi_ec_mul (*r, fact, g, edc->ctx); 276 if (0 !=
457 277 crypto_scalarmult_ed25519_base_noclamp (r_inv->v,
458 /* calculate 'r_inv' */ 278 inv_s))
459 n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1); 279 return GNUNET_SYSERR;
460 gcry_mpi_sub (fact, n, fact); /* fact = n - fact = - fact */ 280 return GNUNET_OK;
461 *r_inv = gcry_mpi_point_new (0);
462 gcry_mpi_ec_mul (*r_inv, fact, g, edc->ctx);
463
464 gcry_mpi_release (n);
465 gcry_mpi_release (fact);
466 gcry_mpi_point_release (g);
467} 281}
468 282
469 283
470/**
471 * Obtain a random scalar for point multiplication on the curve and
472 * its multiplicative inverse.
473 *
474 * @param edc calculation context for ECC operations
475 * @param[out] r set to a random scalar on the curve
476 * @param[out] r_inv set to the multiplicative inverse of @a r
477 */
478void 284void
479GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc, 285GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccScalar *r,
480 gcry_mpi_t *r, 286 struct GNUNET_CRYPTO_EccScalar *r_neg)
481 gcry_mpi_t *r_inv)
482{ 287{
483 gcry_mpi_t n; 288 GNUNET_CRYPTO_ecc_random_mod_n (r);
484 289 crypto_core_ed25519_scalar_negate (r_neg->v,
485 *r = GNUNET_CRYPTO_ecc_random_mod_n (edc); 290 r->v);
486 /* r_inv = n - r = - r */
487 *r_inv = gcry_mpi_new (0);
488 n = gcry_mpi_ec_get_mpi ("n", edc->ctx, 1);
489 gcry_mpi_sub (*r_inv, n, *r);
490} 291}
491 292
492 293
493/**
494 * Free a point value returned by the API.
495 *
496 * @param p point to free
497 */
498void 294void
499GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p) 295GNUNET_CRYPTO_ecc_scalar_from_int (int64_t val,
296 struct GNUNET_CRYPTO_EccScalar *r)
500{ 297{
501 gcry_mpi_point_release (p); 298 unsigned char fact[crypto_scalarmult_ed25519_SCALARBYTES];
299 uint64_t valBe;
300
301 GNUNET_assert (sizeof (*r) == sizeof (fact));
302 if (val < 0)
303 {
304 if (INT64_MIN == val)
305 valBe = GNUNET_htonll ((uint64_t) INT64_MAX);
306 else
307 valBe = GNUNET_htonll ((uint64_t) (-val));
308 }
309 else
310 {
311 valBe = GNUNET_htonll ((uint64_t) val);
312 }
313 memset (fact,
314 0,
315 sizeof (fact));
316 for (unsigned int i = 0; i < sizeof (val); i++)
317 fact[i] = ((unsigned char*) &valBe)[sizeof (val) - 1 - i];
318 if (val < 0)
319 {
320 if (INT64_MIN == val)
321 /* See above: fact is one too small, increment now that we can */
322 sodium_increment (fact,
323 sizeof (fact));
324 crypto_core_ed25519_scalar_negate (r->v,
325 fact);
326 }
327 else
328 {
329 memcpy (r,
330 fact,
331 sizeof (fact));
332 }
502} 333}
503 334
504 335
diff --git a/src/util/perf_crypto_ecc_dlog.c b/src/util/perf_crypto_ecc_dlog.c
index 8a0e4676b..f32ffbd67 100644
--- a/src/util/perf_crypto_ecc_dlog.c
+++ b/src/util/perf_crypto_ecc_dlog.c
@@ -52,72 +52,88 @@
52 */ 52 */
53#define TEST_ITER 10 53#define TEST_ITER 10
54 54
55/**
56 * Range of values to use for MATH tests.
57 */
58#define MATH_MAX 500000
59
60 55
61/** 56/**
62 * Do some DLOG operations for testing. 57 * Do some DLOG operations for testing.
63 * 58 *
64 * @param edc context for ECC operations 59 * @param edc context for ECC operations
65 * @param do_dlog #GNUNET_YES if we want to actually do the bencharked operation 60 * @param do_dlog true if we want to actually do the bencharked operation
66 */ 61 */
67static void 62static void
68test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, 63test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc,
69 int do_dlog) 64 bool do_dlog)
70{ 65{
71 gcry_mpi_t fact; 66 for (unsigned int i = 0; i < TEST_ITER; i++)
72 gcry_mpi_t n;
73 gcry_ctx_t ctx;
74 gcry_mpi_point_t q;
75 gcry_mpi_point_t g;
76 unsigned int i;
77 int x;
78 int iret;
79
80 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
81 g = gcry_mpi_ec_get_point ("g", ctx, 0);
82 GNUNET_assert (NULL != g);
83 n = gcry_mpi_ec_get_mpi ("n", ctx, 0);
84 q = gcry_mpi_point_new (0);
85 fact = gcry_mpi_new (0);
86 for (i = 0; i < TEST_ITER; i++)
87 { 67 {
68 struct GNUNET_CRYPTO_EccScalar fact;
69 struct GNUNET_CRYPTO_EccScalar n;
70 struct GNUNET_CRYPTO_EccPoint q;
71 int x;
72
88 fprintf (stderr, "."); 73 fprintf (stderr, ".");
89 x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 74 x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
90 MAX_FACT); 75 MAX_FACT);
76 memset (&n,
77 0,
78 sizeof (n));
79 for (unsigned int j = 0; j < x; j++)
80 sodium_increment (n.v,
81 sizeof (n.v));
91 if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 82 if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
92 2)) 83 2))
93 { 84 {
94 gcry_mpi_set_ui (fact, x); 85 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
95 gcry_mpi_sub (fact, n, fact); 86 "Trying negative %d\n",
87 -x);
88 crypto_core_ed25519_scalar_negate (fact.v,
89 n.v);
96 x = -x; 90 x = -x;
97 } 91 }
98 else 92 else
99 { 93 {
100 gcry_mpi_set_ui (fact, x); 94 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
95 "Trying positive %d\n",
96 x);
97 fact = n;
101 } 98 }
102 gcry_mpi_ec_mul (q, fact, g, ctx); 99 if (0 == x)
103 if ((GNUNET_YES == do_dlog) &&
104 (x !=
105 (iret = GNUNET_CRYPTO_ecc_dlog (edc,
106 q))))
107 { 100 {
108 fprintf (stderr, 101 /* libsodium does not like to multiply with zero; make sure
109 "DLOG failed for value %d (%d)\n", 102 'q' is a valid point (g) first, then use q = q - q to get
110 x, 103 the product with zero */
111 iret); 104 sodium_increment (fact.v,
112 GNUNET_assert (0); 105 sizeof (fact.v));
106 GNUNET_assert (0 ==
107 crypto_scalarmult_ed25519_base_noclamp (q.v,
108 fact.v));
109 GNUNET_assert (
110 0 ==
111 crypto_core_ed25519_sub (q.v,
112 q.v,
113 q.v));
114 }
115 else
116 GNUNET_assert (0 ==
117 crypto_scalarmult_ed25519_base_noclamp (q.v,
118 fact.v));
119 if (do_dlog)
120 {
121 int iret;
122
123 if (x !=
124 (iret = GNUNET_CRYPTO_ecc_dlog (edc,
125 &q)))
126 {
127 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
128 "DLOG failed for value %d (got: %d)\n",
129 x,
130 iret);
131 GNUNET_assert (0);
132 }
113 } 133 }
114 } 134 }
115 gcry_mpi_release (fact); 135 fprintf (stderr,
116 gcry_mpi_release (n); 136 "\n");
117 gcry_mpi_point_release (g);
118 gcry_mpi_point_release (q);
119 gcry_ctx_release (ctx);
120 fprintf (stderr, "\n");
121} 137}
122 138
123 139
@@ -128,17 +144,6 @@ main (int argc, char *argv[])
128 struct GNUNET_TIME_Absolute start; 144 struct GNUNET_TIME_Absolute start;
129 struct GNUNET_TIME_Relative delta; 145 struct GNUNET_TIME_Relative delta;
130 146
131 if (! gcry_check_version ("1.6.0"))
132 {
133 fprintf (stderr,
134 _
135 (
136 "libgcrypt has not the expected version (version %s is required).\n"),
137 "1.6.0");
138 return 0;
139 }
140 if (getenv ("GNUNET_GCRYPT_DEBUG"))
141 gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
142 GNUNET_log_setup ("perf-crypto-ecc-dlog", 147 GNUNET_log_setup ("perf-crypto-ecc-dlog",
143 "WARNING", 148 "WARNING",
144 NULL); 149 NULL);
@@ -154,10 +159,10 @@ main (int argc, char *argv[])
154 (start).rel_value_us / 1000LL, "ms/op"); 159 (start).rel_value_us / 1000LL, "ms/op");
155 start = GNUNET_TIME_absolute_get (); 160 start = GNUNET_TIME_absolute_get ();
156 /* first do a baseline run without the DLOG */ 161 /* first do a baseline run without the DLOG */
157 test_dlog (edc, GNUNET_NO); 162 test_dlog (edc, false);
158 delta = GNUNET_TIME_absolute_get_duration (start); 163 delta = GNUNET_TIME_absolute_get_duration (start);
159 start = GNUNET_TIME_absolute_get (); 164 start = GNUNET_TIME_absolute_get ();
160 test_dlog (edc, GNUNET_YES); 165 test_dlog (edc, true);
161 delta = GNUNET_TIME_relative_subtract (GNUNET_TIME_absolute_get_duration ( 166 delta = GNUNET_TIME_relative_subtract (GNUNET_TIME_absolute_get_duration (
162 start), 167 start),
163 delta); 168 delta);
@@ -165,7 +170,8 @@ main (int argc, char *argv[])
165 TEST_ITER, 170 TEST_ITER,
166 GNUNET_STRINGS_relative_time_to_string (delta, 171 GNUNET_STRINGS_relative_time_to_string (delta,
167 GNUNET_YES)); 172 GNUNET_YES));
168 GAUGER ("UTIL", "ECC DLOG operations", 173 GAUGER ("UTIL",
174 "ECC DLOG operations",
169 delta.rel_value_us / 1000LL / TEST_ITER, 175 delta.rel_value_us / 1000LL / TEST_ITER,
170 "ms/op"); 176 "ms/op");
171 177
diff --git a/src/util/test_crypto_ecc_dlog.c b/src/util/test_crypto_ecc_dlog.c
index a2c02a94e..51f290d51 100644
--- a/src/util/test_crypto_ecc_dlog.c
+++ b/src/util/test_crypto_ecc_dlog.c
@@ -49,7 +49,7 @@
49/** 49/**
50 * How many values do we test? 50 * How many values do we test?
51 */ 51 */
52#define TEST_ITER 10 52#define TEST_ITER 100
53 53
54/** 54/**
55 * Range of values to use for MATH tests. 55 * Range of values to use for MATH tests.
@@ -65,55 +65,76 @@
65static void 65static void
66test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc) 66test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc)
67{ 67{
68 gcry_mpi_t fact; 68 for (unsigned int i = 0; i < TEST_ITER; i++)
69 gcry_mpi_t n;
70 gcry_ctx_t ctx;
71 gcry_mpi_point_t q;
72 gcry_mpi_point_t g;
73 unsigned int i;
74 int x;
75 int iret;
76
77 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
78 g = gcry_mpi_ec_get_point ("g", ctx, 0);
79 GNUNET_assert (NULL != g);
80 n = gcry_mpi_ec_get_mpi ("n", ctx, 0);
81 q = gcry_mpi_point_new (0);
82 fact = gcry_mpi_new (0);
83 for (i = 0; i < TEST_ITER; i++)
84 { 69 {
70 struct GNUNET_CRYPTO_EccScalar fact;
71 struct GNUNET_CRYPTO_EccScalar n;
72 struct GNUNET_CRYPTO_EccPoint q;
73 int x;
74
85 fprintf (stderr, "."); 75 fprintf (stderr, ".");
86 x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 76 x = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
87 MAX_FACT); 77 MAX_FACT);
78 memset (&n,
79 0,
80 sizeof (n));
81 for (unsigned int j = 0; j < x; j++)
82 sodium_increment (n.v,
83 sizeof (n.v));
88 if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 84 if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
89 2)) 85 2))
90 { 86 {
91 gcry_mpi_set_ui (fact, x); 87 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
92 gcry_mpi_sub (fact, n, fact); 88 "Trying negative %d\n",
89 -x);
90 crypto_core_ed25519_scalar_negate (fact.v,
91 n.v);
93 x = -x; 92 x = -x;
94 } 93 }
95 else 94 else
96 { 95 {
97 gcry_mpi_set_ui (fact, x); 96 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
97 "Trying positive %d\n",
98 x);
99 fact = n;
98 } 100 }
99 gcry_mpi_ec_mul (q, fact, g, ctx); 101 if (0 == x)
100 if (x !=
101 (iret = GNUNET_CRYPTO_ecc_dlog (edc,
102 q)))
103 { 102 {
104 fprintf (stderr, 103 /* libsodium does not like to multiply with zero; make sure
105 "DLOG failed for value %d (%d)\n", 104 'q' is a valid point (g) first, then use q = q - q to get
106 x, 105 the product with zero */
107 iret); 106 sodium_increment (fact.v,
108 GNUNET_assert (0); 107 sizeof (fact.v));
108 GNUNET_assert (0 ==
109 crypto_scalarmult_ed25519_base_noclamp (q.v,
110 fact.v));
111 GNUNET_assert (
112 0 ==
113 crypto_core_ed25519_sub (q.v,
114 q.v,
115 q.v));
116 }
117 else
118 GNUNET_assert (0 ==
119 crypto_scalarmult_ed25519_base_noclamp (q.v,
120 fact.v));
121 {
122 int iret;
123
124 if (x !=
125 (iret = GNUNET_CRYPTO_ecc_dlog (edc,
126 &q)))
127 {
128 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
129 "DLOG failed for value %d (got: %d)\n",
130 x,
131 iret);
132 GNUNET_assert (0);
133 }
109 } 134 }
110 } 135 }
111 gcry_mpi_release (fact); 136 fprintf (stderr,
112 gcry_mpi_release (n); 137 "\n");
113 gcry_mpi_point_release (g);
114 gcry_mpi_point_release (q);
115 gcry_ctx_release (ctx);
116 fprintf (stderr, "\n");
117} 138}
118 139
119 140
@@ -127,38 +148,40 @@ test_math (struct GNUNET_CRYPTO_EccDlogContext *edc)
127{ 148{
128 int i; 149 int i;
129 int j; 150 int j;
130 gcry_mpi_point_t ip; 151 struct GNUNET_CRYPTO_EccPoint ip;
131 gcry_mpi_point_t jp; 152 struct GNUNET_CRYPTO_EccPoint jp;
132 gcry_mpi_point_t r; 153 struct GNUNET_CRYPTO_EccPoint r;
133 gcry_mpi_point_t ir; 154 struct GNUNET_CRYPTO_EccPoint ir;
134 gcry_mpi_point_t irj; 155 struct GNUNET_CRYPTO_EccPoint irj;
135 gcry_mpi_point_t r_inv; 156 struct GNUNET_CRYPTO_EccPoint r_inv;
136 gcry_mpi_point_t sum; 157 struct GNUNET_CRYPTO_EccPoint sum;
137 158
138 for (i = -MATH_MAX; i < MATH_MAX; i++) 159 for (i = -MATH_MAX; i < MATH_MAX; i++)
139 { 160 {
140 ip = GNUNET_CRYPTO_ecc_dexp (edc, i); 161 GNUNET_CRYPTO_ecc_dexp (i, &ip);
141 for (j = -MATH_MAX; j < MATH_MAX; j++) 162 for (j = -MATH_MAX; j < MATH_MAX; j++)
142 { 163 {
143 fprintf (stderr, "."); 164 fprintf (stderr, ".");
144 jp = GNUNET_CRYPTO_ecc_dexp (edc, j); 165 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
145 GNUNET_CRYPTO_ecc_rnd (edc, 166 "%d + %d\n",
146 &r, 167 i,
168 j);
169 GNUNET_CRYPTO_ecc_dexp (j, &jp);
170 GNUNET_CRYPTO_ecc_rnd (&r,
147 &r_inv); 171 &r_inv);
148 ir = GNUNET_CRYPTO_ecc_add (edc, ip, r); 172 GNUNET_CRYPTO_ecc_add (&ip, &r, &ir);
149 irj = GNUNET_CRYPTO_ecc_add (edc, ir, jp); 173 GNUNET_CRYPTO_ecc_add (&ir, &jp, &irj);
150 sum = GNUNET_CRYPTO_ecc_add (edc, irj, r_inv); 174 GNUNET_CRYPTO_ecc_add (&irj, &r_inv, &sum);
151 GNUNET_assert (i + j == 175 int res = GNUNET_CRYPTO_ecc_dlog (edc, &sum);
152 GNUNET_CRYPTO_ecc_dlog (edc, 176 if (i + j != res)
153 sum)); 177 {
154 GNUNET_CRYPTO_ecc_free (jp); 178 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
155 GNUNET_CRYPTO_ecc_free (ir); 179 "Got %d, expected %d\n",
156 GNUNET_CRYPTO_ecc_free (irj); 180 res,
157 GNUNET_CRYPTO_ecc_free (r); 181 i + j);
158 GNUNET_CRYPTO_ecc_free (r_inv); 182 // GNUNET_assert (0);
159 GNUNET_CRYPTO_ecc_free (sum); 183 }
160 } 184 }
161 GNUNET_CRYPTO_ecc_free (ip);
162 } 185 }
163 fprintf (stderr, "\n"); 186 fprintf (stderr, "\n");
164} 187}