GNUnet 0.22.2
crypto_ecc_dlog.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012, 2013, 2015 GNUnet e.V.
4
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
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
29#include "platform.h"
30#include <gcrypt.h>
31#include "gnunet_util_lib.h"
32
33
38{
42 unsigned int max;
43
47 unsigned int mem;
48
56
60 gcry_ctx_t ctx;
61};
62
63
66 unsigned int mem)
67{
69 int K = ((max + (mem - 1)) / mem);
70
71 GNUNET_assert (max < INT32_MAX);
72 GNUNET_assert (mem <= UINT32_MAX / 2);
74 edc->max = max;
75 edc->mem = mem;
77 GNUNET_NO);
78 for (int i = -(int) mem; i <= (int) mem; i++)
79 {
82
84 &Ki);
85 if (0 == i) /* libsodium does not like to multiply with zero */
87 0 ==
88 crypto_core_ed25519_sub ((unsigned char *) &key,
89 (unsigned char *) &key,
90 (unsigned char *) &key));
91 else
93 0 ==
94 crypto_scalarmult_ed25519_base_noclamp ((unsigned char*) &key,
95 Ki.v));
97 "K*i: %d (mem=%u, i=%d) => %s\n",
98 K * i,
99 mem,
100 i,
101 GNUNET_i2s (&key));
104 &key,
105 (void *) (long) i + max,
107 }
108 return edc;
109}
110
111
112int
114 const struct GNUNET_CRYPTO_EccPoint *input)
115{
116 unsigned int K = ((edc->max + (edc->mem - 1)) / edc->mem);
117 int res;
118 struct GNUNET_CRYPTO_EccPoint g;
120 struct GNUNET_CRYPTO_EccPoint nq;
121
122 {
123 struct GNUNET_CRYPTO_EccScalar fact;
124
125 memset (&fact,
126 0,
127 sizeof (fact));
128 sodium_increment (fact.v,
129 sizeof (fact.v));
130 GNUNET_assert (0 ==
131 crypto_scalarmult_ed25519_base_noclamp (g.v,
132 fact.v));
133 }
134 /* make compiler happy: initialize q and nq, technically not needed! */
135 memset (&q,
136 0,
137 sizeof (q));
138 memset (&nq,
139 0,
140 sizeof (nq));
141 res = INT_MAX;
142 for (unsigned int i = 0; i <= edc->max / edc->mem; i++)
143 {
145 void *retp;
146
147 GNUNET_assert (sizeof (key) == crypto_scalarmult_BYTES);
148 if (0 == i)
149 {
150 memcpy (&key,
151 input,
152 sizeof (key));
153 }
154 else
155 {
156 memcpy (&key,
157 &q,
158 sizeof (key));
159 }
161 "Trying offset i=%u): %s\n",
162 i,
163 GNUNET_i2s (&key));
165 &key);
166 if (NULL != retp)
167 {
168 res = (((long) retp) - edc->max) * K - i;
169 /* we continue the loop here to make the implementation
170 "constant-time". If we do not care about this, we could just
171 'break' here and do fewer operations... */
172 }
173 if (i == edc->max / edc->mem)
174 break;
175 /* q = q + g */
176 if (0 == i)
177 {
178 GNUNET_assert (0 ==
179 crypto_core_ed25519_add (q.v,
180 input->v,
181 g.v));
182 }
183 else
184 {
185 GNUNET_assert (0 ==
186 crypto_core_ed25519_add (q.v,
187 q.v,
188 g.v));
189 }
190 }
191 return res;
192}
193
194
195void
197{
198 crypto_core_ed25519_scalar_random (r->v);
199}
200
201
202void
204{
207}
208
209
210void
212 struct GNUNET_CRYPTO_EccPoint *r)
213{
214 struct GNUNET_CRYPTO_EccScalar fact;
215
217 &fact);
218 crypto_scalarmult_ed25519_base_noclamp (r->v,
219 fact.v);
220}
221
222
225 struct GNUNET_CRYPTO_EccPoint *r)
226{
227 if (0 ==
228 crypto_scalarmult_ed25519_base_noclamp (r->v,
229 val->v))
230 return GNUNET_OK;
231 return GNUNET_SYSERR;
232}
233
234
237 const struct GNUNET_CRYPTO_EccPoint *b,
238 struct GNUNET_CRYPTO_EccPoint *r)
239{
240 if (0 ==
241 crypto_core_ed25519_add (r->v,
242 a->v,
243 b->v))
244 return GNUNET_OK;
245 return GNUNET_SYSERR;
246}
247
248
251 const struct GNUNET_CRYPTO_EccScalar *val,
252 struct GNUNET_CRYPTO_EccPoint *r)
253{
254 if (0 ==
255 crypto_scalarmult_ed25519_noclamp (r->v,
256 val->v,
257 p->v))
258 return GNUNET_OK;
259 return GNUNET_SYSERR;
260}
261
262
265 struct GNUNET_CRYPTO_EccPoint *r_inv)
266{
268 unsigned char inv_s[crypto_scalarmult_ed25519_SCALARBYTES];
269
271 if (0 !=
272 crypto_scalarmult_ed25519_base_noclamp (r->v,
273 s.v))
274 return GNUNET_SYSERR;
275 crypto_core_ed25519_scalar_negate (inv_s,
276 s.v);
277 if (0 !=
278 crypto_scalarmult_ed25519_base_noclamp (r_inv->v,
279 inv_s))
280 return GNUNET_SYSERR;
281 return GNUNET_OK;
282}
283
284
285void
287 struct GNUNET_CRYPTO_EccScalar *r_neg)
288{
290 crypto_core_ed25519_scalar_negate (r_neg->v,
291 r->v);
292}
293
294
295void
297 struct GNUNET_CRYPTO_EccScalar *r)
298{
299 unsigned char fact[crypto_scalarmult_ed25519_SCALARBYTES];
300 uint64_t valBe;
301
302 GNUNET_assert (sizeof (*r) == sizeof (fact));
303 if (val < 0)
304 {
305 if (INT64_MIN == val)
306 valBe = GNUNET_htonll ((uint64_t) INT64_MAX);
307 else
308 valBe = GNUNET_htonll ((uint64_t) (-val));
309 }
310 else
311 {
312 valBe = GNUNET_htonll ((uint64_t) val);
313 }
314 memset (fact,
315 0,
316 sizeof (fact));
317 for (unsigned int i = 0; i < sizeof (val); i++)
318 fact[i] = ((unsigned char*) &valBe)[sizeof (val) - 1 - i];
319 if (val < 0)
320 {
321 if (INT64_MIN == val)
322 /* See above: fact is one too small, increment now that we can */
323 sodium_increment (fact,
324 sizeof (fact));
325 crypto_core_ed25519_scalar_negate (r->v,
326 fact);
327 }
328 else
329 {
330 memcpy (r,
331 fact,
332 sizeof (fact));
333 }
334}
335
336
337/* end of crypto_ecc_dlog.c */
#define INT_MAX
struct GNUNET_HashCode key
The key used in the DHT.
static char * res
Currently read line or NULL on EOF.
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
static struct GNUNET_CRYPTO_EccDlogContext * edc
Context for DLOG operations on a curve.
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-uri.c:38
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY
There must only be one value per key; storing a value should fail if a value under the same key alrea...
void GNUNET_CRYPTO_ecc_rnd_mpi(struct GNUNET_CRYPTO_EccScalar *r, struct GNUNET_CRYPTO_EccScalar *r_neg)
Obtain a random scalar for point multiplication on the curve and its additive inverse.
#define GNUNET_log(kind,...)
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_dexp_mpi(const struct GNUNET_CRYPTO_EccScalar *val, struct GNUNET_CRYPTO_EccPoint *r)
Multiply the generator g of the elliptic curve by val to obtain the point on the curve representing v...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_pmul_mpi(const struct GNUNET_CRYPTO_EccPoint *p, const struct GNUNET_CRYPTO_EccScalar *val, struct GNUNET_CRYPTO_EccPoint *r)
Multiply the point p on the elliptic curve by val.
int GNUNET_CRYPTO_ecc_dlog(struct GNUNET_CRYPTO_EccDlogContext *edc, const struct GNUNET_CRYPTO_EccPoint *input)
Calculate ECC discrete logarithm for small factors.
void GNUNET_CRYPTO_ecc_scalar_from_int(int64_t val, struct GNUNET_CRYPTO_EccScalar *r)
Create a scalar from int value.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:37
void GNUNET_CRYPTO_ecc_dexp(int val, struct GNUNET_CRYPTO_EccPoint *r)
Multiply the generator g of the elliptic curve by val to obtain the point on the curve representing v...
void GNUNET_CRYPTO_ecc_dlog_release(struct GNUNET_CRYPTO_EccDlogContext *edc)
Release precalculated values.
struct GNUNET_CRYPTO_EccDlogContext * GNUNET_CRYPTO_ecc_dlog_prepare(unsigned int max, unsigned int mem)
Do pre-calculation for ECC discrete logarithm for small factors.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_rnd(struct GNUNET_CRYPTO_EccPoint *r, struct GNUNET_CRYPTO_EccPoint *r_inv)
Obtain a random point on the curve and its additive inverse.
void GNUNET_CRYPTO_ecc_random_mod_n(struct GNUNET_CRYPTO_EccScalar *r)
Generate a random value mod n.
GNUNET_GenericReturnValue
Named constants for return values.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_add(const struct GNUNET_CRYPTO_EccPoint *a, const struct GNUNET_CRYPTO_EccPoint *b, struct GNUNET_CRYPTO_EccPoint *r)
Add two points on the elliptic curve.
@ GNUNET_OK
@ GNUNET_NO
@ GNUNET_SYSERR
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
#define max(x, y)
Internal representation of the hash map.
Internal structure used to cache pre-calculated values for DLOG calculation.
struct GNUNET_CONTAINER_MultiPeerMap * map
Map mapping points (here "interpreted" as EdDSA public keys) to a "void * = long" which corresponds t...
unsigned int mem
How much memory should we use (relates to the number of entries in the map).
unsigned int max
Maximum absolute value the calculation supports.
gcry_ctx_t ctx
Context to use for operations on the elliptic curve.
Point on a curve (always for Curve25519) encoded in a format suitable for network transmission (ECDH)...
unsigned char v[256/8]
Q consists of an x- and a y-value, each mod p (256 bits), given here in affine coordinates and Ed2551...
A ECC scalar for use in point multiplications.
unsigned char v[256/8]
The identity of the host (wraps the signing key of the peer).