GNUnet 0.21.2
crypto_elligator.c File Reference
#include "gnunet_common.h"
#include "platform.h"
#include <gcrypt.h>
#include <sodium.h>
#include "gnunet_util_lib.h"
#include "benchmark.h"
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <gmp.h>
#include <limits.h>
Include dependency graph for crypto_elligator.c:

Go to the source code of this file.

Macros

#define P_BITS   (256)
 
#define P_BYTES   ((P_BITS + CHAR_BIT - 1) / CHAR_BIT)
 
#define P_LIMBS   ((P_BITS + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
 

Functions

static void decode_bytes (mp_limb_t *number, const uint8_t *bytes)
 
static void encode_bytes (uint8_t *bytes, mp_limb_t *number)
 
void __attribute__ ((constructor))
 Initialize elligator scratch space. More...
 
static void least_square_root (mp_limb_t *root, const mp_limb_t *number, mp_limb_t *scratch_space)
 Calculates the root of a given number. More...
 
bool GNUNET_CRYPTO_ecdhe_elligator_encoding_norand (struct GNUNET_CRYPTO_ElligatorRepresentative *r, uint8_t seed, const struct GNUNET_CRYPTO_EcdhePublicKey *pub)
 
bool GNUNET_CRYPTO_ecdhe_elligator_encoding (struct GNUNET_CRYPTO_ElligatorRepresentative *r, const struct GNUNET_CRYPTO_EcdhePublicKey *pub)
 Encodes a point on Curve25519 to a an element of the underlying finite field. More...
 
static bool elligator_direct_map (uint8_t *point, bool *high_y, uint8_t *representative)
 Takes a number of the underlying finite field of Curve25519 and projects it into a valid point on that curve. More...
 
void GNUNET_CRYPTO_ecdhe_elligator_decoding (struct GNUNET_CRYPTO_EcdhePublicKey *point, bool *high_y, const struct GNUNET_CRYPTO_ElligatorRepresentative *representative)
 Clears the most significant bit and second most significant bit of the serialized representaive before applying elligator direct map. More...
 
static bool convert_from_ed_to_curve (uint8_t *point, const uint8_t *source)
 Takes a number of the underlying finite field of Curve25519 and projects it into a valid point on that curve. More...
 
static enum GNUNET_GenericReturnValue elligator_generate_public_key (const struct GNUNET_CRYPTO_EcdhePrivateKey *pk, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdhe_elligator_key_get_public (const struct GNUNET_CRYPTO_EcdhePrivateKey *sk, struct GNUNET_CRYPTO_EcdhePublicKey *pk, struct GNUNET_CRYPTO_ElligatorRepresentative *repr)
 Generates a valid public key for elligator's inverse map by adding a lower order point to a prime order point. More...
 
void GNUNET_CRYPTO_ecdhe_elligator_key_create (struct GNUNET_CRYPTO_EcdhePrivateKey *sk)
 Generates a private key for Curve25519. More...
 

Variables

static const uint8_t lookupTable [8][crypto_scalarmult_SCALARBYTES]
 
static const unsigned char p_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static const unsigned char negative_1_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static const unsigned char negative_2_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static const unsigned char divide_negative_1_2_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static const unsigned char divide_plus_p_3_8_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static const unsigned char divide_minus_p_1_2_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static const unsigned char square_root_negative_1_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static const unsigned char A_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static const unsigned char negative_A_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static const unsigned char u_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static const unsigned char inverted_u_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static const unsigned char d_bytes [(((256)+CHAR_BIT - 1)/CHAR_BIT)]
 
static mp_limb_t p [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_limb_t negative_1 [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_limb_t negative_2 [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_limb_t divide_negative_1_2 [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_limb_t divide_plus_p_3_8 [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_limb_t divide_minus_p_1_2 [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_limb_t square_root_negative_1 [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_limb_t A [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_limb_t negative_A [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_limb_t u [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_limb_t inverted_u [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_limb_t d [(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
 
static mp_size_t scratch_space_length
 

Macro Definition Documentation

◆ P_BITS

#define P_BITS   (256)

Definition at line 92 of file crypto_elligator.c.

◆ P_BYTES

#define P_BYTES   ((P_BITS + CHAR_BIT - 1) / CHAR_BIT)

Definition at line 93 of file crypto_elligator.c.

◆ P_LIMBS

#define P_LIMBS   ((P_BITS + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)

Definition at line 94 of file crypto_elligator.c.

Function Documentation

◆ decode_bytes()

static void decode_bytes ( mp_limb_t *  number,
const uint8_t *  bytes 
)
static

Definition at line 199 of file crypto_elligator.c.

200{
201 mp_limb_t scratch_space[1];
202
203 for (size_t i = 0; i < P_BYTES; ++i)
204 {
205 mpn_lshift (number, number, P_LIMBS, 8);
206 mpn_sec_add_1 (number, number, 1, bytes[P_BYTES - i - 1], scratch_space);
207 }
208}
#define P_BYTES
#define P_LIMBS
uint32_t number

References number, P_BYTES, and P_LIMBS.

Referenced by __attribute__(), convert_from_ed_to_curve(), elligator_direct_map(), and GNUNET_CRYPTO_ecdhe_elligator_encoding_norand().

Here is the caller graph for this function:

◆ encode_bytes()

static void encode_bytes ( uint8_t *  bytes,
mp_limb_t *  number 
)
static

Definition at line 213 of file crypto_elligator.c.

214{
215 for (size_t i = 0; i < P_BYTES; ++i)
216 {
217 bytes[P_BYTES - i - 1] = mpn_lshift (number, number, P_LIMBS, 8);
218 }
219}

References number, P_BYTES, and P_LIMBS.

Referenced by convert_from_ed_to_curve(), elligator_direct_map(), and GNUNET_CRYPTO_ecdhe_elligator_encoding_norand().

Here is the caller graph for this function:

◆ __attribute__()

void __attribute__ ( (constructor)  )

Initialize elligator scratch space.

Definition at line 225 of file crypto_elligator.c.

227{
228 static bool initialized = false;
229
230 if (initialized)
231 {
232 return;
233 }
234
247
248 mp_size_t scratch_space_lengths[] = {
249 // For least_square_root
250
251 mpn_sec_powm_itch (P_LIMBS, P_BITS - 1, P_LIMBS),
252 mpn_sec_sqr_itch (P_LIMBS),
253 mpn_sec_div_r_itch (P_LIMBS + P_LIMBS, P_LIMBS),
254 mpn_sec_sub_1_itch (P_LIMBS),
255 mpn_sec_mul_itch (P_LIMBS, P_LIMBS),
256
257 // For Elligator_2_Curve25519_encode
258
259 mpn_sec_powm_itch (P_LIMBS, P_BITS - 1, P_LIMBS),
260 mpn_sec_mul_itch (P_LIMBS, P_LIMBS),
261 mpn_sec_div_r_itch (P_LIMBS + P_LIMBS, P_LIMBS),
262 mpn_sec_sqr_itch (P_LIMBS),
263 mpn_sec_sub_1_itch (P_LIMBS),
264
265 // For Elligator_2_Curve25519_decode
266
267 mpn_sec_sqr_itch (P_LIMBS),
268 mpn_sec_div_r_itch (P_LIMBS + P_LIMBS, P_LIMBS),
269 mpn_sec_div_r_itch (P_LIMBS, P_LIMBS),
270 mpn_sec_mul_itch (P_LIMBS, P_LIMBS),
271 mpn_sec_add_1_itch (P_LIMBS),
272 mpn_sec_powm_itch (P_LIMBS, P_BITS - 1, P_LIMBS),
273
274 // For Elligator_2_Curve25519_convert_from_Ed25519
275 mpn_sec_sqr_itch (P_LIMBS),
276 mpn_sec_div_r_itch (P_LIMBS + P_LIMBS, P_LIMBS),
277 mpn_sec_mul_itch (P_LIMBS, P_LIMBS),
278 mpn_sec_add_1_itch (P_LIMBS),
279 mpn_sec_powm_itch (P_LIMBS, P_BITS - 1, P_LIMBS),
280 mpn_sec_sub_1_itch (P_LIMBS)
281 };
282
283 for (size_t i = 0; i < sizeof scratch_space_lengths
284 / sizeof *scratch_space_lengths; ++i)
285 {
286 if (scratch_space_lengths[i] > scratch_space_length)
287 {
288 scratch_space_length = scratch_space_lengths[i];
289 }
290 }
291
292 initialized = true;
293}
static void decode_bytes(mp_limb_t *number, const uint8_t *bytes)
static mp_limb_t divide_minus_p_1_2[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static mp_limb_t negative_A[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static mp_limb_t negative_2[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
#define P_BITS
static mp_limb_t square_root_negative_1[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static mp_limb_t p[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static const unsigned char divide_minus_p_1_2_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static const unsigned char negative_A_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static mp_limb_t d[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static const unsigned char u_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static const unsigned char p_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static const unsigned char negative_1_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static const unsigned char negative_2_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static mp_size_t scratch_space_length
static const unsigned char A_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static const unsigned char square_root_negative_1_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static const unsigned char d_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static mp_limb_t negative_1[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static const unsigned char divide_plus_p_3_8_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static const unsigned char divide_negative_1_2_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static mp_limb_t A[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static mp_limb_t inverted_u[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static mp_limb_t divide_plus_p_3_8[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static mp_limb_t u[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static const unsigned char inverted_u_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static mp_limb_t divide_negative_1_2[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static int initialized
Have we been initialized?
Definition: plugin.c:59

References A, A_bytes, d, d_bytes, decode_bytes(), divide_minus_p_1_2, divide_minus_p_1_2_bytes, divide_negative_1_2, divide_negative_1_2_bytes, divide_plus_p_3_8, divide_plus_p_3_8_bytes, initialized, inverted_u, inverted_u_bytes, negative_1, negative_1_bytes, negative_2, negative_2_bytes, negative_A, negative_A_bytes, p, P_BITS, p_bytes, P_LIMBS, scratch_space_length, square_root_negative_1, square_root_negative_1_bytes, u, and u_bytes.

Here is the call graph for this function:

◆ least_square_root()

static void least_square_root ( mp_limb_t *  root,
const mp_limb_t *  number,
mp_limb_t *  scratch_space 
)
static

Calculates the root of a given number.

Returns trash if the number is a quadratic non-residue.

Parameters
rootstorage for calculated root
numbervalue for which the root is calculated
scratch_spacebuffer for calculation

Definition at line 305 of file crypto_elligator.c.

308{
309 mp_limb_t a[P_LIMBS + P_LIMBS];
310 mp_limb_t b[P_LIMBS];
311
312 // root := number ^ ((p + 3) / 8)
313
314 mpn_add_n (b, number, p, P_LIMBS); // The next function requires a nonzero input
315 mpn_sec_powm (root, b, P_LIMBS, divide_plus_p_3_8, P_BITS - 1, p, P_LIMBS,
316 scratch_space);
317
318 // If root ^ 2 != number, root := root * square_root(-1)
319
320 mpn_sec_sqr (a, root, P_LIMBS, scratch_space);
321 mpn_sec_div_r (a, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
322 mpn_sub_n (b, a, number, P_LIMBS);
323
324 mp_limb_t condition = mpn_sec_sub_1 (b, b, P_LIMBS, 1, scratch_space) ^ 1;
325
326 mpn_sec_mul (a, root, P_LIMBS, square_root_negative_1, P_LIMBS,
327 scratch_space);
328 mpn_sec_div_r (a, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
329
330 mpn_cnd_swap (condition, root, a, P_LIMBS);
331
332 // If root > (p - 1) / 2, root := -root
333
334 condition = mpn_sub_n (a, divide_minus_p_1_2, root, P_LIMBS);
335
336 mpn_sub_n (a, p, root, P_LIMBS); // If root = 0, a := p
337
338 mpn_cnd_swap (condition, root, a, P_LIMBS);
339}

References divide_minus_p_1_2, divide_plus_p_3_8, number, p, P_BITS, P_LIMBS, and square_root_negative_1.

Referenced by GNUNET_CRYPTO_ecdhe_elligator_encoding_norand().

Here is the caller graph for this function:

◆ GNUNET_CRYPTO_ecdhe_elligator_encoding_norand()

bool GNUNET_CRYPTO_ecdhe_elligator_encoding_norand ( struct GNUNET_CRYPTO_ElligatorRepresentative r,
uint8_t  seed,
const struct GNUNET_CRYPTO_EcdhePublicKey pub 
)

Definition at line 342 of file crypto_elligator.c.

346{
347 bool high_y;
348 bool msb_set;
349 bool smsb_set;
350
351 high_y = seed & 1;
352
353 uint8_t *representative = r->r;
354 uint8_t *point = (uint8_t *) pub->q_y;
355
356 mp_limb_t scratch_space[scratch_space_length];
357
358 mp_limb_t a[P_LIMBS + P_LIMBS];
359 mp_limb_t b[P_LIMBS + P_LIMBS];
360 mp_limb_t c[P_LIMBS + P_LIMBS];
361
362 // a := point
363
364 decode_bytes (a, point);
365
366 // b := -a / (a + A), or b := p if a = 0
367
368 mpn_add_n (b, a, A, P_LIMBS);
369 mpn_sec_powm (c, b, P_LIMBS, negative_2, P_BITS - 1, p, P_LIMBS,
370 scratch_space);
371 mpn_sec_mul (b, c, P_LIMBS, a, P_LIMBS, scratch_space);
372 mpn_sec_div_r (b, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
373 mpn_sub_n (b, p, b, P_LIMBS);
374
375 // If high_y = true, b := 1 / b or b := 0 if it was = p
376
377 mpn_sec_powm (c, b, P_LIMBS, negative_2, P_BITS - 1, p, P_LIMBS,
378 scratch_space);
379 mpn_cnd_swap (high_y, b, c, P_LIMBS);
380
381 // c := b / u
382
383 mpn_sec_mul (c, b, P_LIMBS, inverted_u, P_LIMBS, scratch_space);
384 mpn_sec_div_r (c, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
385
386 // If c is a square modulo p, b := least_square_root(c)
387
388 least_square_root (b, c, scratch_space);
389
390 // Determine, whether b ^ 2 = c
391
392 mpn_sec_sqr (a, b, P_LIMBS, scratch_space);
393 mpn_sec_div_r (a, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
394 mpn_sub_n (a, a, c, P_LIMBS);
395
396 bool result = mpn_sec_sub_1 (a, a, P_LIMBS, 1, scratch_space);
397
398 encode_bytes (representative, b);
399
400 // Setting most significant bit and second most significant bit randomly
401 msb_set = (seed >> 1) & 1;
402 smsb_set = (seed >> 2) & 1;
403 if (msb_set)
404 {
405 r->r[31] |= 128;
406 }
407 if (smsb_set)
408 {
409 r->r[31] |= 64;
410 }
411 return result;
412}
static void encode_bytes(uint8_t *bytes, mp_limb_t *number)
static void least_square_root(mp_limb_t *root, const mp_limb_t *number, mp_limb_t *scratch_space)
Calculates the root of a given number.
static int result
Global testing status.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:47
unsigned char q_y[256/8]
Point Q consists of a y-value mod p (256 bits); the x-value is always positive.
uint8_t r[256/8]
Represents an element of Curve25519 finite field.

References A, decode_bytes(), encode_bytes(), inverted_u, least_square_root(), negative_2, p, P_BITS, P_LIMBS, pub, GNUNET_CRYPTO_EddsaPublicKey::q_y, GNUNET_CRYPTO_ElligatorRepresentative::r, result, and scratch_space_length.

Referenced by GNUNET_CRYPTO_ecdhe_elligator_encoding().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ elligator_direct_map()

static bool elligator_direct_map ( uint8_t *  point,
bool *  high_y,
uint8_t *  representative 
)
static

Takes a number of the underlying finite field of Curve25519 and projects it into a valid point on that curve.

This function works deterministically. This step is also known as elligators "decoding" step. Taken from https://github.com/Kleshni/Elligator-2/blob/master/main.c.

Parameters
pointstorage for calculated point on Curve25519
high_yThe 'high_y' argument of the corresponding GNUNET_CRYPTO_ecdhe_elligator_encoding call
representativeGiven representative
Returns
'false' if extra step during direct map calculation is needed, otherwise 'true'

Definition at line 441 of file crypto_elligator.c.

444{
445 mp_limb_t scratch_space[scratch_space_length];
446
447 mp_limb_t a[P_LIMBS + P_LIMBS];
448 mp_limb_t b[P_LIMBS + P_LIMBS];
449 mp_limb_t c[P_LIMBS];
450 mp_limb_t e[P_LIMBS + P_LIMBS];
451
452 // a := representative
453
454 decode_bytes (a, representative);
455
456 // Determine whether a < (p - 1) / 2
457
458 bool result = mpn_sub_n (b, divide_minus_p_1_2, a, P_LIMBS) ^ 1;
459
460 // b := -A / (1 + u * a ^ 2)
461
462 mpn_sec_sqr (b, a, P_LIMBS, scratch_space);
463 mpn_sec_div_r (b, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
464 mpn_sec_mul (a, u, P_LIMBS, b, P_LIMBS, scratch_space);
465 mpn_sec_div_r (a, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
466 mpn_sec_add_1 (b, a, P_LIMBS, 1, scratch_space);
467 mpn_sec_powm (a, b, P_LIMBS, negative_2, P_BITS - 1, p, P_LIMBS,
468 scratch_space);
469 mpn_sec_mul (b, a, P_LIMBS, negative_A, P_LIMBS, scratch_space);
470 mpn_sec_div_r (b, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
471
472 // a := b ^ 3 + A * b ^ 2 + b (with 1-bit overflow)
473
474 mpn_sec_sqr (a, b, P_LIMBS, scratch_space);
475 mpn_sec_div_r (a, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
476 mpn_add_n (c, b, A, P_LIMBS);
477 mpn_sec_mul (e, c, P_LIMBS, a, P_LIMBS, scratch_space);
478 mpn_sec_div_r (e, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
479 mpn_add_n (a, e, b, P_LIMBS);
480
481 // If a is a quadratic residue modulo p, point := b and high_y := 1
482 // Otherwise point := -b - A and high_y := 0
483
484 mpn_sub_n (c, p, b, P_LIMBS);
485 mpn_add_n (c, c, negative_A, P_LIMBS);
486 mpn_sec_div_r (c, P_LIMBS, p, P_LIMBS, scratch_space);
487
488 mpn_sec_powm (e, a, P_LIMBS, divide_minus_p_1_2, P_BITS - 1, p, P_LIMBS,
489 scratch_space);
490 *high_y = mpn_sub_n (e, e, divide_minus_p_1_2, P_LIMBS);
491
492 mpn_cnd_swap (*high_y, b, c, P_LIMBS);
493
494 encode_bytes (point, c);
495
496 return result;
497}

References A, decode_bytes(), divide_minus_p_1_2, encode_bytes(), negative_2, negative_A, p, P_BITS, P_LIMBS, result, scratch_space_length, and u.

Referenced by GNUNET_CRYPTO_ecdhe_elligator_decoding().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ convert_from_ed_to_curve()

static bool convert_from_ed_to_curve ( uint8_t *  point,
const uint8_t *  source 
)
static

Takes a number of the underlying finite field of Curve25519 and projects it into a valid point on that curve.

This function works deterministically. This step is also known as elligators "decoding" step. Taken from https://github.com/Kleshni/Elligator-2/blob/master/main.c.

Parameters
pointstorage for calculated point on Curve25519
sourceEd25519 curve point
Returns
'false' if source is not a valid Ed25519 point. In this case the 'point' array will be undefined but dependent on source.

Definition at line 535 of file crypto_elligator.c.

537{
538 mp_limb_t scratch_space[scratch_space_length];
539
540 mp_limb_t y[P_LIMBS];
541 mp_limb_t a[P_LIMBS + P_LIMBS];
542 mp_limb_t b[P_LIMBS + P_LIMBS];
543 mp_limb_t c[P_LIMBS + P_LIMBS];
544
545 uint8_t y_bytes[P_BYTES];
546
547 memcpy (y_bytes, source, 31);
548
549 y_bytes[31] = source[31] & 0x7f;
550
551 decode_bytes (y, y_bytes);
552
553 // Check if y < p
554
555 bool result = mpn_sub_n (a, y, p, P_LIMBS);
556
557 // a := (y ^ 2 - 1) / (1 + d * y ^ 2)
558
559 mpn_sec_sqr (a, y, P_LIMBS, scratch_space);
560 mpn_sec_div_r (a, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
561 mpn_sec_mul (b, a, P_LIMBS, d, P_LIMBS, scratch_space);
562 mpn_sec_add_1 (b, b, P_LIMBS, 1, scratch_space);
563 mpn_sec_div_r (b, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
564 mpn_sec_powm (c, b, P_LIMBS, negative_2, P_BITS - 1, p, P_LIMBS,
565 scratch_space);
566 mpn_add_n (b, a, negative_1, P_LIMBS);
567 mpn_sec_mul (a, b, P_LIMBS, c, P_LIMBS, scratch_space);
568 mpn_sec_div_r (a, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
569
570 // Check, whether a is a square modulo p (including a = 0)
571
572 mpn_add_n (a, a, p, P_LIMBS);
573 mpn_sec_powm (b, a, P_LIMBS, divide_negative_1_2, P_BITS - 1, p, P_LIMBS,
574 scratch_space);
575
576 result &= mpn_sub_n (c, b, divide_minus_p_1_2, P_LIMBS);
577
578 // If a = p, the parity bit must be 0
579
580 mpn_sub_n (a, a, p, P_LIMBS);
581
582 result ^= mpn_sec_sub_1 (a, a, P_LIMBS, 1, scratch_space) & source[31] >> 7;
583
584 // If y != 1, c := (1 + y) / (1 - y), otherwise c := 0
585
586 mpn_sub_n (a, p, y, P_LIMBS);
587 mpn_sec_add_1 (a, a, P_LIMBS, 1, scratch_space);
588 mpn_sec_powm (b, a, P_LIMBS, negative_2, P_BITS - 1, p, P_LIMBS,
589 scratch_space);
590 mpn_sec_add_1 (a, y, P_LIMBS, 1, scratch_space);
591 mpn_sec_mul (c, a, P_LIMBS, b, P_LIMBS, scratch_space);
592 mpn_sec_div_r (c, P_LIMBS + P_LIMBS, p, P_LIMBS, scratch_space);
593
594 encode_bytes (point, c);
595
596 return result;
597}
static GstElement * source
Appsrc instance into which we write data for the pipeline.

References d, decode_bytes(), divide_minus_p_1_2, divide_negative_1_2, encode_bytes(), negative_1, negative_2, p, P_BITS, P_BYTES, P_LIMBS, result, scratch_space_length, and source.

Referenced by elligator_generate_public_key().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ elligator_generate_public_key()

static enum GNUNET_GenericReturnValue elligator_generate_public_key ( const struct GNUNET_CRYPTO_EcdhePrivateKey pk,
struct GNUNET_CRYPTO_EcdhePublicKey pub 
)
static

Definition at line 601 of file crypto_elligator.c.

604{
605 // eHigh
606 // crypto_scalarmult_ed25519_base clamps the scalar pk->d and return only 0 if pk->d is zero
607 unsigned char eHigh[crypto_scalarmult_SCALARBYTES] = {0};
608 GNUNET_assert (0 == crypto_scalarmult_ed25519_base (eHigh, pk->d));
609
610 // eLow: choose a random point of low order
611 int sLow = (pk->d)[0] % 8;
612 unsigned char eLow[crypto_scalarmult_SCALARBYTES] = {0};
613 memcpy (eLow, lookupTable[sLow], crypto_scalarmult_SCALARBYTES);
614
615 // eHigh + eLow
616 unsigned char edPub[crypto_scalarmult_SCALARBYTES] = {0};
617 if (crypto_core_ed25519_add (edPub, eLow, eHigh) == -1)
618 {
619 return GNUNET_SYSERR;
620 }
621
622 if (convert_from_ed_to_curve (pub->q_y, edPub) == false)
623 {
624 return GNUNET_SYSERR;
625 }
626 return GNUNET_OK;
627}
static const uint8_t lookupTable[8][crypto_scalarmult_SCALARBYTES]
static bool convert_from_ed_to_curve(uint8_t *point, const uint8_t *source)
Takes a number of the underlying finite field of Curve25519 and projects it into a valid point on tha...
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.

References convert_from_ed_to_curve(), GNUNET_assert, GNUNET_OK, GNUNET_SYSERR, lookupTable, pk, pub, and GNUNET_CRYPTO_EddsaPublicKey::q_y.

Referenced by GNUNET_CRYPTO_ecdhe_elligator_key_get_public().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ lookupTable

const uint8_t lookupTable[8][crypto_scalarmult_SCALARBYTES]
static

Definition at line 42 of file crypto_elligator.c.

Referenced by elligator_generate_public_key().

◆ p_bytes

const unsigned char p_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
}

Definition at line 98 of file crypto_elligator.c.

Referenced by __attribute__().

◆ negative_1_bytes

const unsigned char negative_1_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
}

Definition at line 105 of file crypto_elligator.c.

Referenced by __attribute__().

◆ negative_2_bytes

const unsigned char negative_2_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0xeb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
}

Definition at line 112 of file crypto_elligator.c.

Referenced by __attribute__().

◆ divide_negative_1_2_bytes

const unsigned char divide_negative_1_2_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f
}

Definition at line 119 of file crypto_elligator.c.

Referenced by __attribute__().

◆ divide_plus_p_3_8_bytes

const unsigned char divide_plus_p_3_8_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f
}

Definition at line 126 of file crypto_elligator.c.

Referenced by __attribute__().

◆ divide_minus_p_1_2_bytes

const unsigned char divide_minus_p_1_2_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f
}

Definition at line 133 of file crypto_elligator.c.

Referenced by __attribute__().

◆ square_root_negative_1_bytes

const unsigned char square_root_negative_1_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0xb0, 0xa0, 0x0e, 0x4a, 0x27, 0x1b, 0xee, 0xc4,
0x78, 0xe4, 0x2f, 0xad, 0x06, 0x18, 0x43, 0x2f,
0xa7, 0xd7, 0xfb, 0x3d, 0x99, 0x00, 0x4d, 0x2b,
0x0b, 0xdf, 0xc1, 0x4f, 0x80, 0x24, 0x83, 0x2b
}

Definition at line 140 of file crypto_elligator.c.

Referenced by __attribute__().

◆ A_bytes

const unsigned char A_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0x06, 0x6d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

Definition at line 147 of file crypto_elligator.c.

Referenced by __attribute__().

◆ negative_A_bytes

const unsigned char negative_A_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0xe7, 0x92, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
}

Definition at line 154 of file crypto_elligator.c.

Referenced by __attribute__().

◆ u_bytes

const unsigned char u_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}

Definition at line 161 of file crypto_elligator.c.

Referenced by __attribute__().

◆ inverted_u_bytes

const unsigned char inverted_u_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f
}

Definition at line 168 of file crypto_elligator.c.

Referenced by __attribute__().

◆ d_bytes

const unsigned char d_bytes[(((256)+CHAR_BIT - 1)/CHAR_BIT)]
static
Initial value:
= {
0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52
}

Definition at line 175 of file crypto_elligator.c.

Referenced by __attribute__().

◆ p

mp_limb_t p[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static

◆ negative_1

mp_limb_t negative_1[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static

Definition at line 183 of file crypto_elligator.c.

Referenced by __attribute__(), and convert_from_ed_to_curve().

◆ negative_2

mp_limb_t negative_2[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static

◆ divide_negative_1_2

mp_limb_t divide_negative_1_2[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static

Definition at line 185 of file crypto_elligator.c.

Referenced by __attribute__(), and convert_from_ed_to_curve().

◆ divide_plus_p_3_8

mp_limb_t divide_plus_p_3_8[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static

Definition at line 186 of file crypto_elligator.c.

Referenced by __attribute__(), and least_square_root().

◆ divide_minus_p_1_2

mp_limb_t divide_minus_p_1_2[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static

◆ square_root_negative_1

mp_limb_t square_root_negative_1[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static

Definition at line 188 of file crypto_elligator.c.

Referenced by __attribute__(), and least_square_root().

◆ A

mp_limb_t A[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static

◆ negative_A

mp_limb_t negative_A[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static

Definition at line 190 of file crypto_elligator.c.

Referenced by __attribute__(), and elligator_direct_map().

◆ u

◆ inverted_u

mp_limb_t inverted_u[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static

◆ d

◆ scratch_space_length

mp_size_t scratch_space_length
static