diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/gnunet_crypto_lib.h | 132 | ||||
-rw-r--r-- | src/include/gnunet_scalarproduct_service.h | 50 | ||||
-rw-r--r-- | src/scalarproduct/Makefile.am | 4 | ||||
-rw-r--r-- | src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c | 297 | ||||
-rw-r--r-- | src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c | 131 | ||||
-rwxr-xr-x | src/scalarproduct/perf_scalarproduct.sh | 19 | ||||
-rw-r--r-- | src/scalarproduct/scalarproduct_api.c | 50 | ||||
-rw-r--r-- | src/scalarproduct/test_ecc_scalarproduct.c | 211 | ||||
-rwxr-xr-x | src/scalarproduct/test_scalarproduct_negative.sh | 3 | ||||
-rw-r--r-- | src/util/Makefile.am | 3 | ||||
-rw-r--r-- | src/util/crypto_ecc_dlog.c | 525 | ||||
-rw-r--r-- | src/util/perf_crypto_ecc_dlog.c | 118 | ||||
-rw-r--r-- | src/util/test_crypto_ecc_dlog.c | 141 |
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 | */ | ||
1452 | struct 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 | */ |
1457 | struct GNUNET_CRYPTO_EccDlogContext * | 1464 | struct GNUNET_CRYPTO_EccDlogContext * |
1458 | GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, unsigned int mem); | 1465 | GNUNET_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 | */ |
1469 | int | 1477 | int |
1470 | GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, | 1478 | GNUNET_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 | */ |
1487 | gcry_mpi_point_t | 1493 | void |
1488 | GNUNET_CRYPTO_ecc_dexp (struct GNUNET_CRYPTO_EccDlogContext *edc, int val); | 1494 | GNUNET_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 | */ |
1500 | gcry_mpi_point_t | 1506 | enum GNUNET_GenericReturnValue |
1501 | GNUNET_CRYPTO_ecc_dexp_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc, | 1507 | GNUNET_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 | */ | ||
1514 | gcry_mpi_point_t | ||
1515 | GNUNET_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 | */ | ||
1527 | void | ||
1528 | GNUNET_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 | */ |
1540 | gcry_mpi_point_t | 1519 | enum GNUNET_GenericReturnValue |
1541 | GNUNET_CRYPTO_ecc_bin_to_point (struct GNUNET_CRYPTO_EccDlogContext *edc, | 1520 | GNUNET_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 | */ |
1553 | gcry_mpi_point_t | 1533 | enum GNUNET_GenericReturnValue |
1554 | GNUNET_CRYPTO_ecc_add (struct GNUNET_CRYPTO_EccDlogContext *edc, | 1534 | GNUNET_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 | */ |
1568 | void | 1547 | enum GNUNET_GenericReturnValue |
1569 | GNUNET_CRYPTO_ecc_rnd (struct GNUNET_CRYPTO_EccDlogContext *edc, | 1548 | GNUNET_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 | */ |
1582 | void | 1559 | void |
1583 | GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc, | 1560 | GNUNET_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 | */ |
1594 | gcry_mpi_t | 1569 | void |
1595 | GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc); | 1570 | GNUNET_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 | */ |
1603 | void | 1578 | void |
1604 | GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p); | 1579 | GNUNET_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 | */ |
1612 | void | 1588 | void |
1613 | GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *dlc); | 1589 | GNUNET_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 | */ |
1939 | void | 1917 | void |
1940 | GNUNET_CRYPTO_mpi_print_unsigned (void *buf, size_t size, gcry_mpi_t val); | 1918 | GNUNET_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 | */ |
120 | typedef void | 119 | typedef 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 | */ |
134 | typedef void | 132 | typedef 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 | */ |
159 | struct GNUNET_SCALARPRODUCT_ComputationHandle * | 157 | struct GNUNET_SCALARPRODUCT_ComputationHandle * |
160 | GNUNET_SCALARPRODUCT_start_computation (const struct | 158 | GNUNET_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 | */ |
183 | struct GNUNET_SCALARPRODUCT_ComputationHandle * | 179 | struct GNUNET_SCALARPRODUCT_ComputationHandle * |
184 | GNUNET_SCALARPRODUCT_accept_computation (const struct | 180 | GNUNET_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 |
112 | test_ecc_scalarproduct_LDADD = \ | 114 | test_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 | */ |
193 | static gcry_mpi_t my_privkey; | 193 | static 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 | */ |
198 | static gcry_mpi_t my_privkey_inv; | 198 | static 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 | */ |
214 | static int | 214 | static int |
215 | free_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value) | 215 | free_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) | |||
229 | static void | 231 | static void |
230 | destroy_service_session (struct AliceServiceSession *s) | 232 | destroy_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 | */ |
396 | static void | 395 | static void |
397 | cb_channel_destruction (void *cls, const struct GNUNET_CADET_Channel *channel) | 396 | cb_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 | */ | ||
423 | static gcry_mpi_t | ||
424 | compute_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 | */ |
519 | static int | 489 | static int |
520 | copy_element_cb (void *cls, const struct GNUNET_HashCode *key, void *value) | 490 | copy_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 | */ |
547 | static int | 512 | static int |
548 | element_cmp (const void *a, const void *b) | 513 | element_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, | |||
775 | static void | 766 | static void |
776 | client_request_complete_alice (struct AliceServiceSession *s) | 767 | client_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, | |||
1031 | static void | 1027 | static void |
1032 | shutdown_task (void *cls) | 1028 | shutdown_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, | |||
213 | static void | 213 | static void |
214 | destroy_service_session (struct BobServiceSession *s) | 214 | destroy_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 | */ |
392 | static int | 371 | static int |
393 | copy_element_cb (void *cls, | 372 | copy_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 | */ |
749 | static int | 722 | static int |
750 | check_bob_client_message_multipart (void *cls, | 723 | check_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 | */ |
783 | static void | 755 | static void |
784 | handle_bob_client_message_multipart (void *cls, | 756 | handle_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: |
17 | SIZE=800 | 30 | SIZE=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 | */ |
44 | typedef void | 44 | typedef 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 | */ |
229 | struct GNUNET_SCALARPRODUCT_ComputationHandle * | 224 | struct GNUNET_SCALARPRODUCT_ComputationHandle * |
230 | GNUNET_SCALARPRODUCT_accept_computation (const struct | 225 | GNUNET_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 | */ |
391 | struct GNUNET_SCALARPRODUCT_ComputationHandle * | 383 | struct GNUNET_SCALARPRODUCT_ComputationHandle * |
392 | GNUNET_SCALARPRODUCT_start_computation (const struct | 384 | GNUNET_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 | |||
154 | int | 189 | int |
155 | main (int argc, char *argv[]) | 190 | main (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;'" | |||
5 | INPUTBOB="-k CCC -e 'BC,-20000;RO,1000;FL,100;LOL,24;'" | 5 | INPUTBOB="-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 |
8 | unset XDG_DATA_HOME | ||
9 | unset XDG_CONFIG_HOME | ||
10 | |||
8 | PREFIX=/tmp/test-scalarproduct`date +%H%M%S` | 11 | PREFIX=/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 | |||
460 | test_crypto_ecc_dlog_SOURCES = \ | 460 | test_crypto_ecc_dlog_SOURCES = \ |
461 | test_crypto_ecc_dlog.c | 461 | test_crypto_ecc_dlog.c |
462 | test_crypto_ecc_dlog_LDADD = \ | 462 | test_crypto_ecc_dlog_LDADD = \ |
463 | -lsodium \ | ||
463 | libgnunetutil.la \ | 464 | libgnunetutil.la \ |
464 | $(LIBGCRYPT_LIBS) | 465 | $(LIBGCRYPT_LIBS) |
465 | endif | 466 | endif |
@@ -610,7 +611,7 @@ perf_crypto_ecc_dlog_SOURCES = \ | |||
610 | perf_crypto_ecc_dlog.c | 611 | perf_crypto_ecc_dlog.c |
611 | perf_crypto_ecc_dlog_LDADD = \ | 612 | perf_crypto_ecc_dlog_LDADD = \ |
612 | libgnunetutil.la \ | 613 | libgnunetutil.la \ |
613 | -lgcrypt | 614 | -lsodium |
614 | endif | 615 | endif |
615 | 616 | ||
616 | perf_crypto_rsa_SOURCES = \ | 617 | perf_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 | */ | ||
46 | static void | ||
47 | extract_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 | */ |
66 | struct GNUNET_CRYPTO_EccDlogContext | 37 | struct 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 | */ | ||
100 | void | ||
101 | GNUNET_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 | */ | ||
124 | gcry_mpi_point_t | ||
125 | GNUNET_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 | */ | ||
156 | struct GNUNET_CRYPTO_EccDlogContext * | 64 | struct GNUNET_CRYPTO_EccDlogContext * |
157 | GNUNET_CRYPTO_ecc_dlog_prepare (unsigned int max, | 65 | GNUNET_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 | */ | ||
224 | int | 111 | int |
225 | GNUNET_CRYPTO_ecc_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, | 112 | GNUNET_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 | /** | 194 | void |
272 | * Generate a random value mod n. | 195 | GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccScalar *r) |
273 | * | ||
274 | * @param edc ECC context | ||
275 | * @return random value mod n. | ||
276 | */ | ||
277 | gcry_mpi_t | ||
278 | GNUNET_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 | */ | ||
311 | void | 201 | void |
312 | GNUNET_CRYPTO_ecc_dlog_release (struct GNUNET_CRYPTO_EccDlogContext *edc) | 202 | GNUNET_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 | /** | 209 | void |
321 | * Multiply the generator g of the elliptic curve by @a val | 210 | GNUNET_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 | */ | ||
333 | gcry_mpi_point_t | ||
334 | GNUNET_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 | /** | 222 | enum GNUNET_GenericReturnValue |
365 | * Multiply the generator g of the elliptic curve by @a val | 223 | GNUNET_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 | */ | ||
373 | gcry_mpi_point_t | ||
374 | GNUNET_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 | /** | 234 | enum GNUNET_GenericReturnValue |
390 | * Add two points on the elliptic curve. | 235 | GNUNET_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 | */ | ||
397 | gcry_mpi_point_t | ||
398 | GNUNET_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 | /** | 248 | enum GNUNET_GenericReturnValue |
411 | * Multiply the point @a p on the elliptic curve by @a val. | 249 | GNUNET_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 | */ | ||
419 | gcry_mpi_point_t | ||
420 | GNUNET_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 | /** | 262 | enum GNUNET_GenericReturnValue |
433 | * Obtain a random point on the curve and its | 263 | GNUNET_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 | */ | ||
441 | void | ||
442 | GNUNET_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 | */ | ||
478 | void | 284 | void |
479 | GNUNET_CRYPTO_ecc_rnd_mpi (struct GNUNET_CRYPTO_EccDlogContext *edc, | 285 | GNUNET_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 | */ | ||
498 | void | 294 | void |
499 | GNUNET_CRYPTO_ecc_free (gcry_mpi_point_t p) | 295 | GNUNET_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 | */ |
67 | static void | 62 | static void |
68 | test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc, | 63 | test_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 @@ | |||
65 | static void | 65 | static void |
66 | test_dlog (struct GNUNET_CRYPTO_EccDlogContext *edc) | 66 | test_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 | } |