GNUnet 0.28.0-dev.3-7-g31e20e2e6
 
Loading...
Searching...
No Matches
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 "gnunet_util_lib.h"
31
32
37{
41 unsigned int max;
42
46 unsigned int mem;
47
55
56};
57
58
61 unsigned int mem)
62{
64 int K = ((max + (mem - 1)) / mem);
65
66 GNUNET_assert (max < INT32_MAX);
67 GNUNET_assert (mem <= UINT32_MAX / 2);
69 edc->max = max;
70 edc->mem = mem;
72 GNUNET_NO);
73 for (int i = -(int) mem; i <= (int) mem; i++)
74 {
77
79 &Ki);
80 if (0 == i) /* libsodium does not like to multiply with zero */
82 0 ==
83 crypto_core_ed25519_sub ((unsigned char *) &key,
84 (unsigned char *) &key,
85 (unsigned char *) &key));
86 else
88 0 ==
89 crypto_scalarmult_ed25519_base_noclamp ((unsigned char*) &key,
90 Ki.v));
92 "K*i: %d (mem=%u, i=%d) => %s\n",
93 K * i,
94 mem,
95 i,
96 GNUNET_i2s (&key));
99 &key,
100 (void *) (long) i + max,
102 }
103 return edc;
104}
105
106
107int
109 const struct GNUNET_CRYPTO_EccPoint *input)
110{
111 unsigned int K = ((edc->max + (edc->mem - 1)) / edc->mem);
112 int res;
113 struct GNUNET_CRYPTO_EccPoint g;
115 struct GNUNET_CRYPTO_EccPoint nq;
116
117 {
118 struct GNUNET_CRYPTO_EccScalar fact;
119
120 memset (&fact,
121 0,
122 sizeof (fact));
123 sodium_increment (fact.v,
124 sizeof (fact.v));
125 GNUNET_assert (0 ==
126 crypto_scalarmult_ed25519_base_noclamp (g.v,
127 fact.v));
128 }
129 /* make compiler happy: initialize q and nq, technically not needed! */
130 memset (&q,
131 0,
132 sizeof (q));
133 memset (&nq,
134 0,
135 sizeof (nq));
136 res = INT_MAX;
137 for (unsigned int i = 0; i <= edc->max / edc->mem; i++)
138 {
140 void *retp;
141
142 GNUNET_assert (sizeof (key) == crypto_scalarmult_BYTES);
143 if (0 == i)
144 {
145 memcpy (&key,
146 input,
147 sizeof (key));
148 }
149 else
150 {
151 memcpy (&key,
152 &q,
153 sizeof (key));
154 }
156 "Trying offset i=%u): %s\n",
157 i,
158 GNUNET_i2s (&key));
160 &key);
161 if (NULL != retp)
162 {
163 res = (((long) retp) - edc->max) * K - i;
164 /* we continue the loop here to make the implementation
165 "constant-time". If we do not care about this, we could just
166 'break' here and do fewer operations... */
167 }
168 if (i == edc->max / edc->mem)
169 break;
170 /* q = q + g */
171 if (0 == i)
172 {
173 GNUNET_assert (0 ==
174 crypto_core_ed25519_add (q.v,
175 input->v,
176 g.v));
177 }
178 else
179 {
180 GNUNET_assert (0 ==
181 crypto_core_ed25519_add (q.v,
182 q.v,
183 g.v));
184 }
185 }
186 return res;
187}
188
189
190void
192{
193 crypto_core_ed25519_scalar_random (r->v);
194}
195
196
197void
203
204
205void
207 struct GNUNET_CRYPTO_EccPoint *r)
208{
209 struct GNUNET_CRYPTO_EccScalar fact;
210
212 &fact);
213 crypto_scalarmult_ed25519_base_noclamp (r->v,
214 fact.v);
215}
216
217
220 struct GNUNET_CRYPTO_EccPoint *r)
221{
222 if (0 ==
223 crypto_scalarmult_ed25519_base_noclamp (r->v,
224 val->v))
225 return GNUNET_OK;
226 return GNUNET_SYSERR;
227}
228
229
232 const struct GNUNET_CRYPTO_EccPoint *b,
233 struct GNUNET_CRYPTO_EccPoint *r)
234{
235 if (0 ==
236 crypto_core_ed25519_add (r->v,
237 a->v,
238 b->v))
239 return GNUNET_OK;
240 return GNUNET_SYSERR;
241}
242
243
246 const struct GNUNET_CRYPTO_EccScalar *val,
247 struct GNUNET_CRYPTO_EccPoint *r)
248{
249 if (0 ==
250 crypto_scalarmult_ed25519_noclamp (r->v,
251 val->v,
252 p->v))
253 return GNUNET_OK;
254 return GNUNET_SYSERR;
255}
256
257
260 struct GNUNET_CRYPTO_EccPoint *r_inv)
261{
263 unsigned char inv_s[crypto_scalarmult_ed25519_SCALARBYTES];
264
266 if (0 !=
267 crypto_scalarmult_ed25519_base_noclamp (r->v,
268 s.v))
269 return GNUNET_SYSERR;
270 crypto_core_ed25519_scalar_negate (inv_s,
271 s.v);
272 if (0 !=
273 crypto_scalarmult_ed25519_base_noclamp (r_inv->v,
274 inv_s))
275 return GNUNET_SYSERR;
276 return GNUNET_OK;
277}
278
279
280void
282 struct GNUNET_CRYPTO_EccScalar *r_neg)
283{
285 crypto_core_ed25519_scalar_negate (r_neg->v,
286 r->v);
287}
288
289
290void
292 struct GNUNET_CRYPTO_EccScalar *r)
293{
294 unsigned char fact[crypto_scalarmult_ed25519_SCALARBYTES];
295 uint64_t valBe;
296
297 GNUNET_assert (sizeof (*r) == sizeof (fact));
298 if (val < 0)
299 {
300 if (INT64_MIN == val)
301 valBe = GNUNET_htonll ((uint64_t) INT64_MAX);
302 else
303 valBe = GNUNET_htonll ((uint64_t) (-val));
304 }
305 else
306 {
307 valBe = GNUNET_htonll ((uint64_t) val);
308 }
309 memset (fact,
310 0,
311 sizeof (fact));
312 for (unsigned int i = 0; i < sizeof (val); i++)
313 fact[i] = ((unsigned char*) &valBe)[sizeof (val) - 1 - i];
314 if (val < 0)
315 {
316 if (INT64_MIN == val)
317 /* See above: fact is one too small, increment now that we can */
318 sodium_increment (fact,
319 sizeof (fact));
320 crypto_core_ed25519_scalar_negate (r->v,
321 fact);
322 }
323 else
324 {
325 memcpy (r,
326 fact,
327 sizeof (fact));
328 }
329}
330
331
332/* 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_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.
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.
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.
The identity of the host (wraps the signing key of the peer).