iPXE
Data Structures | Macros | Functions | Variables
x25519.c File Reference

X25519 key exchange. More...

#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <ipxe/init.h>
#include <ipxe/crypto.h>
#include <ipxe/x25519.h>

Go to the source code of this file.

Data Structures

union  x25519_multiply_step1
 X25519 multiplication step 1 result. More...
 
union  x25519_multiply_step2
 X25519 multiplication step 2 result. More...
 
union  x25519_multiply_step3
 X25519 multiplication step 3 result. More...
 
union  x25519_multiply_workspace
 X25519 multiplication temporary working space. More...
 
struct  x25519_projective
 An X25519 elliptic curve point in projective coordinates. More...
 
struct  x25519_step
 An X25519 Montgomery ladder step. More...
 

Macros

#define X25519_REDUCE_256   38
 X25519 reduction constant. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static bigint_t (bigint_required_size(sizeof(x25519_reduce_256_raw)))
 Reduction constant (used during multiplication) More...
 
static void x25519_init_constants (void)
 Initialise constants. More...
 
struct init_fn x25519_init_fn __init_fn (INIT_NORMAL)
 Initialisation function. More...
 
static void x25519_add (const union x25519_quad257 *augend, const union x25519_quad257 *addend, union x25519_oct258 *result)
 Add big integers modulo field prime. More...
 
static void x25519_subtract (const union x25519_quad257 *minuend, const union x25519_quad257 *subtrahend, union x25519_oct258 *result)
 Subtract big integers modulo field prime. More...
 
void x25519_multiply (const union x25519_oct258 *multiplicand, const union x25519_oct258 *multiplier, union x25519_quad257 *result)
 Multiply big integers modulo field prime. More...
 
void x25519_invert (const union x25519_oct258 *invertend, union x25519_quad257 *result)
 Compute multiplicative inverse. More...
 
static void x25519_reduce_by (const x25519_t *subtrahend, x25519_t *value)
 Reduce big integer via conditional subtraction. More...
 
void x25519_reduce (union x25519_quad257 *value)
 Reduce big integer to canonical range. More...
 
static void x25519_step (const union x25519_quad257 *base, int bit, struct x25519_step *step)
 Compute next step of the Montgomery ladder. More...
 
static void x25519_ladder (const union x25519_quad257 *base, struct x25519_value *scalar, union x25519_quad257 *result)
 Multiply X25519 elliptic curve point. More...
 
static void x25519_reverse (struct x25519_value *value)
 Reverse X25519 value endianness. More...
 
int x25519_key (const struct x25519_value *base, const struct x25519_value *scalar, struct x25519_value *result)
 Calculate X25519 key. More...
 
static int x25519_curve_multiply (const void *base, const void *scalar, void *result)
 Multiply scalar by curve point. More...
 

Variables

union x25519_multiply_step1 __attribute__
 
static const uint8_t x25519_p_raw []
 Constant p=2^255-19 (the finite field prime) More...
 
static x25519_t x25519_p
 Constant p=2^255-19 (the finite field prime) More...
 
static x25519_t x25519_2p
 Constant 2p=2^256-38. More...
 
static x25519_t x25519_4p
 Constant 4p=2^257-76. More...
 
static const uint8_t x25519_reduce_256_raw [] = { X25519_REDUCE_256 }
 Reduction constant (used during multiplication) More...
 
static union x25519_oct258 x25519_121665
 Constant 121665 (used in the Montgomery ladder) More...
 
static struct x25519_value x25519_generator
 Constant g=9 (the group generator) More...
 
struct elliptic_curve x25519_curve
 X25519 elliptic curve. More...
 

Detailed Description

X25519 key exchange.

This implementation is inspired by and partially based upon the paper "Implementing Curve25519/X25519: A Tutorial on Elliptic Curve Cryptography" by Martin Kleppmann, available for download from https://www.cl.cam.ac.uk/teaching/2122/Crypto/curve25519.pdf

The underlying modular addition, subtraction, and multiplication operations are completely redesigned for substantially improved efficiency compared to the TweetNaCl implementation studied in that paper.

                           TweetNaCl            iPXE
                           ---------            ----

Storage size of each big integer 128 40 (in bytes)

Stack usage for key exchange 1144 360 (in bytes, large objects only)

Cost of big integer addition 16 5 (in number of 64-bit additions)

Cost of big integer multiplication 273 31 (in number of 64-bit multiplications)

The implementation is constant-time (provided that the underlying big integer operations are also constant-time).

Definition in file x25519.c.

Macro Definition Documentation

◆ X25519_REDUCE_256

#define X25519_REDUCE_256   38

X25519 reduction constant.

The X25519 field prime is p=2^255-19. This gives us:

          p = 2^255 - 19
      2^255 = p + 19
      2^255 = 19          (mod p)
  k * 2^255 = k * 19      (mod p)

We can therefore reduce a value modulo p by taking the high-order bits of the value from bit 255 and above, multiplying by 19, and adding this to the low-order 255 bits of the value.

This would be cumbersome to do in practice since it would require partitioning the value at a 255-bit boundary (and hence would require some shifting and masking operations). However, we can note that:

  k * 2^255 = k * 19      (mod p)

k * 2 * 2^255 = k * 2 * 19 (mod p) k * 2^256 = k * 38 (mod p)

We can therefore simplify the reduction to taking the high order bits of the value from bit 256 and above, multiplying by 38, and adding this to the low-order 256 bits of the value.

Since 256 will inevitably be a multiple of the big integer element size (typically 32 or 64 bits), this avoids the need to perform any shifting or masking operations.

Definition at line 97 of file x25519.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ bigint_t()

static bigint_t ( bigint_required_size(sizeof(x25519_reduce_256_raw))  )
static

Reduction constant (used during multiplication)

Constant 121665 (used in the Montgomery ladder)

Definition at line 295 of file x25519.c.

299  { 0x01, 0xdb, 0x41 };

◆ x25519_init_constants()

static void x25519_init_constants ( void  )
static

Initialise constants.

Definition at line 313 of file x25519.c.

313  {
314 
315  /* Construct constant p */
316  bigint_init ( &x25519_p, x25519_p_raw, sizeof ( x25519_p_raw ) );
317 
318  /* Construct constant 2p */
321 
322  /* Construct constant 4p */
325 
326  /* Construct reduction constant */
327  bigint_init ( &x25519_reduce_256, x25519_reduce_256_raw,
328  sizeof ( x25519_reduce_256_raw ) );
329 
330  /* Construct constant 121665 */
331  bigint_init ( &x25519_121665.value, x25519_121665_raw,
332  sizeof ( x25519_121665_raw ) );
333 }
static const uint8_t x25519_reduce_256_raw[]
Reduction constant (used during multiplication)
Definition: x25519.c:292
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:50
static x25519_t x25519_4p
Constant 4p=2^257-76.
Definition: x25519.c:289
static x25519_t x25519_p
Constant p=2^255-19 (the finite field prime)
Definition: x25519.c:283
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:187
static x25519_t x25519_2p
Constant 2p=2^256-38.
Definition: x25519.c:286
static const uint8_t x25519_p_raw[]
Constant p=2^255-19 (the finite field prime)
Definition: x25519.c:275
#define bigint_add(addend, value)
Add big integers.
Definition: bigint.h:74
static union x25519_oct258 x25519_121665
Constant 121665 (used in the Montgomery ladder)
Definition: x25519.c:302
x25519_t value
Big integer value.
Definition: x25519.h:47

References bigint_add, bigint_copy, bigint_init, x25519_oct258::value, x25519_121665, x25519_2p, x25519_4p, x25519_p, x25519_p_raw, and x25519_reduce_256_raw.

◆ __init_fn()

struct init_fn x25519_init_fn __init_fn ( INIT_NORMAL  )

Initialisation function.

◆ x25519_add()

static void x25519_add ( const union x25519_quad257 augend,
const union x25519_quad257 addend,
union x25519_oct258 result 
)
inlinestatic

Add big integers modulo field prime.

Parameters
augendBig integer to add
addendBig integer to add
resultBig integer to hold result (may overlap augend)

Definition at line 348 of file x25519.c.

350  {
351  int copy;
352 
353  /* Copy augend if necessary */
354  copy = ( result != &augend->oct258 );
355  build_assert ( __builtin_constant_p ( copy ) );
356  if ( copy ) {
357  build_assert ( result != &addend->oct258 );
358  bigint_copy ( &augend->oct258.value, &result->value );
359  }
360 
361  /* Perform addition
362  *
363  * Both inputs are in the range [0,4p-1] and the resulting
364  * sum is therefore in the range [0,8p-2].
365  *
366  * This range lies within the range [0,8p-1] and the result is
367  * therefore a valid X25519 unsigned 258-bit integer, as
368  * required.
369  */
370  bigint_add ( &addend->value, &result->value );
371 }
static const void const void void * result
Definition: crypto.h:335
const union x25519_oct258 oct258
X25519 unsigned 258-bit integer.
Definition: x25519.h:73
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:187
#define build_assert(condition)
Assert a condition at build time (after dead code elimination)
Definition: assert.h:76
x25519_t value
Big integer value.
Definition: x25519.h:66
#define bigint_add(addend, value)
Add big integers.
Definition: bigint.h:74
x25519_t value
Big integer value.
Definition: x25519.h:47

References bigint_add, bigint_copy, build_assert, x25519_quad257::oct258, result, x25519_oct258::value, and x25519_quad257::value.

Referenced by x25519_step().

◆ x25519_subtract()

static void x25519_subtract ( const union x25519_quad257 minuend,
const union x25519_quad257 subtrahend,
union x25519_oct258 result 
)
inlinestatic

Subtract big integers modulo field prime.

Parameters
minuendBig integer from which to subtract
subtrahendBig integer to subtract
resultBig integer to hold result (may overlap minuend)

Definition at line 381 of file x25519.c.

383  {
384  int copy;
385 
386  /* Copy minuend if necessary */
387  copy = ( result != &minuend->oct258 );
388  build_assert ( __builtin_constant_p ( copy ) );
389  if ( copy ) {
390  build_assert ( result != &subtrahend->oct258 );
391  bigint_copy ( &minuend->oct258.value, &result->value );
392  }
393 
394  /* Perform subtraction
395  *
396  * Both inputs are in the range [0,4p-1] and the resulting
397  * difference is therefore in the range [1-4p,4p-1].
398  *
399  * This range lies partially outside the range [0,8p-1] and
400  * the result is therefore not yet a valid X25519 unsigned
401  * 258-bit integer.
402  */
403  bigint_subtract ( &subtrahend->value, &result->value );
404 
405  /* Add constant multiple of field prime p
406  *
407  * Add the constant 4p to the result. This brings the result
408  * within the range [1,8p-1] (without changing the value
409  * modulo p).
410  *
411  * This range lies within the range [0,8p-1] and the result is
412  * therefore now a valid X25519 unsigned 258-bit integer, as
413  * required.
414  */
415  bigint_add ( &x25519_4p, &result->value );
416 }
static const void const void void * result
Definition: crypto.h:335
const union x25519_oct258 oct258
X25519 unsigned 258-bit integer.
Definition: x25519.h:73
static x25519_t x25519_4p
Constant 4p=2^257-76.
Definition: x25519.c:289
static __always_inline off_t userptr_t subtrahend
Definition: efi_uaccess.h:61
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:187
#define build_assert(condition)
Assert a condition at build time (after dead code elimination)
Definition: assert.h:76
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:85
#define bigint_add(addend, value)
Add big integers.
Definition: bigint.h:74
x25519_t value
Big integer value.
Definition: x25519.h:47

References bigint_add, bigint_copy, bigint_subtract, build_assert, x25519_quad257::oct258, result, subtrahend, x25519_oct258::value, and x25519_4p.

Referenced by x25519_step().

◆ x25519_multiply()

void x25519_multiply ( const union x25519_oct258 multiplicand,
const union x25519_oct258 multiplier,
union x25519_quad257 result 
)

Multiply big integers modulo field prime.

Parameters
multiplicandBig integer to be multiplied
multiplierBig integer to be multiplied
resultBig integer to hold result (may overlap either input)

Definition at line 425 of file x25519.c.

427  {
429  union x25519_multiply_step1 *step1 = &tmp.step1;
430  union x25519_multiply_step2 *step2 = &tmp.step2;
431  union x25519_multiply_step3 *step3 = &tmp.step3;
432 
433  /* Step 1: perform raw multiplication
434  *
435  * step1 = multiplicand * multiplier
436  *
437  * Both inputs are 258-bit numbers and the step 1 result is
438  * therefore 258+258=516 bits.
439  */
440  static_assert ( sizeof ( step1->product ) >= sizeof ( step1->parts ) );
441  bigint_multiply ( &multiplicand->value, &multiplier->value,
442  &step1->product );
443 
444  /* Step 2: reduce high-order 516-256=260 bits of step 1 result
445  *
446  * Use the identity 2^256=38 (mod p) to reduce the high-order
447  * bits of the step 1 result. We split the 516-bit result
448  * from step 1 into its low-order 256 bits and high-order 260
449  * bits:
450  *
451  * step1 = step1(low 256 bits) + step1(high 260 bits) * 2^256
452  *
453  * and then perform the calculation:
454  *
455  * step2 = step1 (mod p)
456  * = step1(low 256 bits) + step1(high 260 bits) * 2^256 (mod p)
457  * = step1(low 256 bits) + step1(high 260 bits) * 38 (mod p)
458  *
459  * There are 6 bits in the constant value 38. The step 2
460  * multiplication product will therefore have 260+6=266 bits,
461  * and the step 2 result (after the addition) will therefore
462  * have 267 bits.
463  */
464  static_assert ( sizeof ( step2->product ) >= sizeof ( step2->value ) );
465  static_assert ( sizeof ( step2->product ) >= sizeof ( step2->parts ) );
466  bigint_grow ( &step1->parts.low_256bit, &result->value );
467  bigint_multiply ( &step1->parts.high_260bit, &x25519_reduce_256,
468  &step2->product );
469  bigint_add ( &result->value, &step2->value );
470 
471  /* Step 3: reduce high-order 267-256=11 bits of step 2 result
472  *
473  * Use the identity 2^256=38 (mod p) again to reduce the
474  * high-order bits of the step 2 result. As before, we split
475  * the 267-bit result from step 2 into its low-order 256 bits
476  * and high-order 11 bits:
477  *
478  * step2 = step2(low 256 bits) + step2(high 11 bits) * 2^256
479  *
480  * and then perform the calculation:
481  *
482  * step3 = step2 (mod p)
483  * = step2(low 256 bits) + step2(high 11 bits) * 2^256 (mod p)
484  * = step2(low 256 bits) + step2(high 11 bits) * 38 (mod p)
485  *
486  * There are 6 bits in the constant value 38. The step 3
487  * multiplication product will therefore have 11+6=19 bits,
488  * and the step 3 result (after the addition) will therefore
489  * have 257 bits.
490  *
491  * A loose upper bound for the step 3 result (after the
492  * addition) is given by:
493  *
494  * step3 < ( 2^256 - 1 ) + ( 2^19 - 1 )
495  * < ( 2^257 - 2^256 - 1 ) + ( 2^19 - 1 )
496  * < ( 2^257 - 76 ) - 2^256 + 2^19 + 74
497  * < 4 * ( 2^255 - 19 ) - 2^256 + 2^19 + 74
498  * < 4p - 2^256 + 2^19 + 74
499  *
500  * and so the step 3 result is strictly less than 4p, and
501  * therefore lies within the range [0,4p-1].
502  */
503  memset ( &step3->value, 0, sizeof ( step3->value ) );
504  bigint_grow ( &step2->parts.low_256bit, &result->value );
505  bigint_multiply ( &step2->parts.high_11bit, &x25519_reduce_256,
506  &step3->product );
507  bigint_add ( &step3->value, &result->value );
508 
509  /* Step 1 calculates the product of the input operands, and
510  * each subsequent step reduces the number of bits in the
511  * result while preserving this value (modulo p). The final
512  * result is therefore equal to the product of the input
513  * operands (modulo p), as required.
514  *
515  * The step 3 result lies within the range [0,4p-1] and the
516  * final result is therefore a valid X25519 unsigned 257-bit
517  * integer, as required.
518  */
519 }
static const void const void void * result
Definition: crypto.h:335
#define bigint_grow(source, dest)
Grow big integer.
Definition: bigint.h:161
#define static_assert(x)
Assert a condition at build time.
Definition: assert.h:65
uint8_t multiplier
Port multiplier number.
Definition: edd.h:32
unsigned long tmp
Definition: linux_pci.h:53
X25519 multiplication step 2 result.
Definition: x25519.c:144
struct x25519_multiply_step1::@432 parts
Partition into low-order and high-order bits.
X25519 multiplication step 3 result.
Definition: x25519.c:188
X25519 multiplication step 1 result.
Definition: x25519.c:107
X25519 multiplication temporary working space.
Definition: x25519.c:216
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:212
#define bigint_add(addend, value)
Add big integers.
Definition: bigint.h:74
x25519_t value
Big integer value.
Definition: x25519.h:47
void * memset(void *dest, int character, size_t len) __nonnull

References bigint_add, bigint_grow, bigint_multiply, memset(), multiplier, x25519_multiply_step1::parts, x25519_multiply_step2::parts, result, static_assert, tmp, and x25519_oct258::value.

Referenced by x25519_invert(), x25519_invert_okx(), x25519_ladder(), x25519_multiply_okx(), and x25519_step().

◆ x25519_invert()

void x25519_invert ( const union x25519_oct258 invertend,
union x25519_quad257 result 
)

Compute multiplicative inverse.

Parameters
invertendBig integer to be inverted
resultBig integer to hold result (may not overlap input)

Definition at line 527 of file x25519.c.

528  {
529  int i;
530 
531  /* Sanity check */
532  assert ( invertend != &result->oct258 );
533 
534  /* Calculate inverse as x^(-1)=x^(p-2) where p is the field prime
535  *
536  * The field prime is p=2^255-19 and so:
537  *
538  * p - 2 = 2^255 - 21
539  * = (2^255 - 1) - 2^4 - 2^2
540  *
541  * i.e. p-2 is a 254-bit number in which all bits are set
542  * apart from bit 2 and bit 4.
543  *
544  * We use the square-and-multiply method to compute x^(p-2).
545  */
546  bigint_copy ( &invertend->value, &result->value );
547  for ( i = 253 ; i >= 0 ; i-- ) {
548 
549  /* Square running total */
550  x25519_multiply ( &result->oct258, &result->oct258, result );
551 
552  /* For each set bit in the exponent, multiply by invertend */
553  if ( ( i != 2 ) && ( i != 4 ) ) {
554  x25519_multiply ( invertend, &result->oct258, result );
555  }
556  }
557 }
static const void const void void * result
Definition: crypto.h:335
void x25519_multiply(const union x25519_oct258 *multiplicand, const union x25519_oct258 *multiplier, union x25519_quad257 *result)
Multiply big integers modulo field prime.
Definition: x25519.c:425
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:187
x25519_t value
Big integer value.
Definition: x25519.h:47

References assert(), bigint_copy, result, x25519_oct258::value, and x25519_multiply().

Referenced by x25519_invert_okx(), and x25519_ladder().

◆ x25519_reduce_by()

static void x25519_reduce_by ( const x25519_t *  subtrahend,
x25519_t *  value 
)
static

Reduce big integer via conditional subtraction.

Parameters
subtrahendBig integer to subtract
valueBig integer to be subtracted from, if possible

Definition at line 565 of file x25519.c.

565  {
566  unsigned int max_bit = ( ( 8 * sizeof ( *value ) ) - 1 );
567  x25519_t tmp;
568 
569  /* Conditionally subtract subtrahend
570  *
571  * Subtract the subtrahend, discarding the result (in constant
572  * time) if the subtraction underflows.
573  */
574  bigint_copy ( value, &tmp );
576  bigint_swap ( value, &tmp, bigint_bit_is_set ( value, max_bit ) );
577 }
static __always_inline off_t userptr_t subtrahend
Definition: efi_uaccess.h:61
unsigned long tmp
Definition: linux_pci.h:53
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:187
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define bigint_swap(first, second, swap)
Conditionally swap big integers (in constant time)
Definition: bigint.h:199
#define bigint_bit_is_set(value, bit)
Test if bit is set in big integer.
Definition: bigint.h:141
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:85

References bigint_bit_is_set, bigint_copy, bigint_subtract, bigint_swap, subtrahend, tmp, and value.

Referenced by x25519_reduce().

◆ x25519_reduce()

void x25519_reduce ( union x25519_quad257 value)

Reduce big integer to canonical range.

Parameters
valueBig integer to be reduced

Definition at line 584 of file x25519.c.

584  {
585 
586  /* Conditionally subtract 2p
587  *
588  * Subtract twice the field prime, discarding the result (in
589  * constant time) if the subtraction underflows.
590  *
591  * The input value is in the range [0,4p-1]. After this
592  * conditional subtraction, the value is in the range
593  * [0,2p-1].
594  */
595  x25519_reduce_by ( &x25519_2p, &value->value );
596 
597  /* Conditionally subtract p
598  *
599  * Subtract the field prime, discarding the result (in
600  * constant time) if the subtraction underflows.
601  *
602  * The value is already in the range [0,2p-1]. After this
603  * conditional subtraction, the value is in the range [0,p-1]
604  * and is therefore the canonical representation.
605  */
606  x25519_reduce_by ( &x25519_p, &value->value );
607 }
static x25519_t x25519_p
Constant p=2^255-19 (the finite field prime)
Definition: x25519.c:283
static void x25519_reduce_by(const x25519_t *subtrahend, x25519_t *value)
Reduce big integer via conditional subtraction.
Definition: x25519.c:565
static x25519_t x25519_2p
Constant 2p=2^256-38.
Definition: x25519.c:286
pseudo_bit_t value[0x00020]
Definition: arbel.h:13

References value, x25519_2p, x25519_p, and x25519_reduce_by().

Referenced by x25519_invert_okx(), x25519_ladder(), and x25519_multiply_okx().

◆ x25519_step()

static void x25519_step ( const union x25519_quad257 base,
int  bit,
struct x25519_step step 
)
static

Compute next step of the Montgomery ladder.

Parameters
baseBase point
bitBit value
stepLadder step

Definition at line 616 of file x25519.c.

617  {
618  union x25519_quad257 *a = &step->x_n.X;
619  union x25519_quad257 *b = &step->x_n1.X;
620  union x25519_quad257 *c = &step->x_n.Z;
621  union x25519_quad257 *d = &step->x_n1.Z;
622  union x25519_oct258 e;
623  union x25519_quad257 f;
624  union x25519_oct258 *v1_e;
625  union x25519_oct258 *v2_a;
626  union x25519_oct258 *v3_c;
627  union x25519_oct258 *v4_b;
628  union x25519_quad257 *v5_d;
629  union x25519_quad257 *v6_f;
630  union x25519_quad257 *v7_a;
631  union x25519_quad257 *v8_c;
632  union x25519_oct258 *v9_e;
633  union x25519_oct258 *v10_a;
634  union x25519_quad257 *v11_b;
635  union x25519_oct258 *v12_c;
636  union x25519_quad257 *v13_a;
637  union x25519_oct258 *v14_a;
638  union x25519_quad257 *v15_c;
639  union x25519_quad257 *v16_a;
640  union x25519_quad257 *v17_d;
641  union x25519_quad257 *v18_b;
642 
643  /* See the referenced paper "Implementing Curve25519/X25519: A
644  * Tutorial on Elliptic Curve Cryptography" for the reasoning
645  * behind this calculation.
646  */
647 
648  /* Reuse storage locations for intermediate results where possible */
649  v1_e = &e;
650  v2_a = container_of ( &a->value, union x25519_oct258, value );
651  v3_c = container_of ( &c->value, union x25519_oct258, value );
652  v4_b = container_of ( &b->value, union x25519_oct258, value );
653  v5_d = d;
654  v6_f = &f;
655  v7_a = a;
656  v8_c = c;
657  v9_e = &e;
658  v10_a = container_of ( &a->value, union x25519_oct258, value );
659  v11_b = b;
660  v12_c = container_of ( &c->value, union x25519_oct258, value );
661  v13_a = a;
662  v14_a = container_of ( &a->value, union x25519_oct258, value );
663  v15_c = c;
664  v16_a = a;
665  v17_d = d;
666  v18_b = b;
667 
668  /* Select inputs */
669  bigint_swap ( &a->value, &b->value, bit );
670  bigint_swap ( &c->value, &d->value, bit );
671 
672  /* v1 = a + c */
673  x25519_add ( a, c, v1_e );
674 
675  /* v2 = a - c */
676  x25519_subtract ( a, c, v2_a );
677 
678  /* v3 = b + d */
679  x25519_add ( b, d, v3_c );
680 
681  /* v4 = b - d */
682  x25519_subtract ( b, d, v4_b );
683 
684  /* v5 = v1^2 = (a + c)^2 = a^2 + 2ac + c^2 */
685  x25519_multiply ( v1_e, v1_e, v5_d );
686 
687  /* v6 = v2^2 = (a - c)^2 = a^2 - 2ac + c^2 */
688  x25519_multiply ( v2_a, v2_a, v6_f );
689 
690  /* v7 = v3 * v2 = (b + d) * (a - c) = ab - bc + ad - cd */
691  x25519_multiply ( v3_c, v2_a, v7_a );
692 
693  /* v8 = v4 * v1 = (b - d) * (a + c) = ab + bc - ad - cd */
694  x25519_multiply ( v4_b, v1_e, v8_c );
695 
696  /* v9 = v7 + v8 = 2 * (ab - cd) */
697  x25519_add ( v7_a, v8_c, v9_e );
698 
699  /* v10 = v7 - v8 = 2 * (ad - bc) */
700  x25519_subtract ( v7_a, v8_c, v10_a );
701 
702  /* v11 = v10^2 = 4 * (ad - bc)^2 */
703  x25519_multiply ( v10_a, v10_a, v11_b );
704 
705  /* v12 = v5 - v6 = (a + c)^2 - (a - c)^2 = 4ac */
706  x25519_subtract ( v5_d, v6_f, v12_c );
707 
708  /* v13 = v12 * 121665 = 486660ac = (A-2) * ac */
709  x25519_multiply ( v12_c, &x25519_121665, v13_a );
710 
711  /* v14 = v13 + v5 = (A-2) * ac + a^2 + 2ac + c^2 = a^2 + A * ac + c^2 */
712  x25519_add ( v13_a, v5_d, v14_a );
713 
714  /* v15 = v12 * v14 = 4ac * (a^2 + A * ac + c^2) */
715  x25519_multiply ( v12_c, v14_a, v15_c );
716 
717  /* v16 = v5 * v6 = (a + c)^2 * (a - c)^2 = (a^2 - c^2)^2 */
718  x25519_multiply ( &v5_d->oct258, &v6_f->oct258, v16_a );
719 
720  /* v17 = v11 * base = 4 * base * (ad - bc)^2 */
721  x25519_multiply ( &v11_b->oct258, &base->oct258, v17_d );
722 
723  /* v18 = v9^2 = 4 * (ab - cd)^2 */
724  x25519_multiply ( v9_e, v9_e, v18_b );
725 
726  /* Select outputs */
727  bigint_swap ( &a->value, &b->value, bit );
728  bigint_swap ( &c->value, &d->value, bit );
729 }
uint32_t c
Definition: md4.c:30
void x25519_multiply(const union x25519_oct258 *multiplicand, const union x25519_oct258 *multiplier, union x25519_quad257 *result)
Multiply big integers modulo field prime.
Definition: x25519.c:425
const union x25519_oct258 oct258
X25519 unsigned 258-bit integer.
Definition: x25519.h:73
static unsigned int unsigned int bit
Definition: bigint.h:208
An X25519 unsigned 257-bit integer.
Definition: x25519.h:64
An X25519 unsigned 258-bit integer.
Definition: x25519.h:45
static const void * base
Base address.
Definition: crypto.h:335
uint32_t a
Definition: md4.c:28
uint32_t e
Definition: sha1.c:32
static void x25519_subtract(const union x25519_quad257 *minuend, const union x25519_quad257 *subtrahend, union x25519_oct258 *result)
Subtract big integers modulo field prime.
Definition: x25519.c:381
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void x25519_add(const union x25519_quad257 *augend, const union x25519_quad257 *addend, union x25519_oct258 *result)
Add big integers modulo field prime.
Definition: x25519.c:348
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define bigint_swap(first, second, swap)
Conditionally swap big integers (in constant time)
Definition: bigint.h:199
void step(void)
Single-step a single process.
Definition: process.c:98
uint32_t b
Definition: md4.c:29
uint32_t d
Definition: md4.c:31
uint32_t f
Definition: sha256.c:33
static union x25519_oct258 x25519_121665
Constant 121665 (used in the Montgomery ladder)
Definition: x25519.c:302

References a, b, base, bigint_swap, bit, c, container_of, d, e, f, x25519_quad257::oct258, step(), value, x25519_121665, x25519_add(), x25519_multiply(), and x25519_subtract().

Referenced by x25519_ladder().

◆ x25519_ladder()

static void x25519_ladder ( const union x25519_quad257 base,
struct x25519_value scalar,
union x25519_quad257 result 
)
static

Multiply X25519 elliptic curve point.

Parameters
baseBase point
scalarScalar multiple
resultPoint to hold result (may overlap base point)

Definition at line 738 of file x25519.c.

740  {
741  static const uint8_t zero[] = { 0 };
742  static const uint8_t one[] = { 1 };
743  struct x25519_step step;
744  union x25519_quad257 *tmp;
745  int bit;
746  int i;
747 
748  /* Initialise ladder */
749  bigint_init ( &step.x_n.X.value, one, sizeof ( one ) );
750  bigint_init ( &step.x_n.Z.value, zero, sizeof ( zero ) );
751  bigint_copy ( &base->value, &step.x_n1.X.value );
752  bigint_init ( &step.x_n1.Z.value, one, sizeof ( one ) );
753 
754  /* Use ladder */
755  for ( i = 254 ; i >= 0 ; i-- ) {
756  bit = ( ( scalar->raw[ i / 8 ] >> ( i % 8 ) ) & 1 );
757  x25519_step ( base, bit, &step );
758  }
759 
760  /* Convert back to affine coordinate */
761  tmp = &step.x_n1.X;
762  x25519_invert ( &step.x_n.Z.oct258, tmp );
763  x25519_multiply ( &step.x_n.X.oct258, &tmp->oct258, result );
764  x25519_reduce ( result );
765 }
static void x25519_step(const union x25519_quad257 *base, int bit, struct x25519_step *step)
Compute next step of the Montgomery ladder.
Definition: x25519.c:616
void x25519_reduce(union x25519_quad257 *value)
Reduce big integer to canonical range.
Definition: x25519.c:584
static const void const void void * result
Definition: crypto.h:335
void x25519_multiply(const union x25519_oct258 *multiplicand, const union x25519_oct258 *multiplier, union x25519_quad257 *result)
Multiply big integers modulo field prime.
Definition: x25519.c:425
static unsigned int unsigned int bit
Definition: bigint.h:208
An X25519 unsigned 257-bit integer.
Definition: x25519.h:64
An X25519 Montgomery ladder step.
Definition: x25519.c:267
static const void const void * scalar
Definition: crypto.h:335
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:50
uint32_t zero
Must be zero.
Definition: ntlm.h:24
static const void * base
Base address.
Definition: crypto.h:335
unsigned long tmp
Definition: linux_pci.h:53
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:187
unsigned char uint8_t
Definition: stdint.h:10
void step(void)
Single-step a single process.
Definition: process.c:98
void x25519_invert(const union x25519_oct258 *invertend, union x25519_quad257 *result)
Compute multiplicative inverse.
Definition: x25519.c:527

References base, bigint_copy, bigint_init, bit, result, scalar, step(), tmp, x25519_invert(), x25519_multiply(), x25519_reduce(), x25519_step(), and zero.

Referenced by x25519_key().

◆ x25519_reverse()

static void x25519_reverse ( struct x25519_value value)
static

Reverse X25519 value endianness.

Parameters
valueValue to reverse

Definition at line 772 of file x25519.c.

772  {
773  uint8_t *low = value->raw;
774  uint8_t *high = &value->raw[ sizeof ( value->raw ) - 1 ];
775  uint8_t tmp;
776 
777  /* Reverse bytes */
778  do {
779  tmp = *low;
780  *low = *high;
781  *high = tmp;
782  } while ( ++low < --high );
783 }
uint32_t low
Low 16 bits of address.
Definition: myson.h:19
unsigned long tmp
Definition: linux_pci.h:53
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
uint32_t high
High 32 bits of address.
Definition: myson.h:20
unsigned char uint8_t
Definition: stdint.h:10

References high, low, tmp, and value.

Referenced by x25519_key().

◆ x25519_key()

int x25519_key ( const struct x25519_value base,
const struct x25519_value scalar,
struct x25519_value result 
)

Calculate X25519 key.

Parameters
baseBase point
scalarScalar multiple
resultPoint to hold result (may overlap base point)
Return values
rcReturn status code

Definition at line 793 of file x25519.c.

795  {
796  struct x25519_value *tmp = result;
797  union x25519_quad257 point;
798 
799  /* Reverse base point and clear high bit as required by RFC7748 */
800  memcpy ( tmp, base, sizeof ( *tmp ) );
801  x25519_reverse ( tmp );
802  tmp->raw[0] &= 0x7f;
803  bigint_init ( &point.value, tmp->raw, sizeof ( tmp->raw ) );
804 
805  /* Clamp scalar as required by RFC7748 */
806  memcpy ( tmp, scalar, sizeof ( *tmp ) );
807  tmp->raw[0] &= 0xf8;
808  tmp->raw[31] |= 0x40;
809 
810  /* Multiply elliptic curve point */
811  x25519_ladder ( &point, tmp, &point );
812 
813  /* Reverse result */
814  bigint_done ( &point.value, result->raw, sizeof ( result->raw ) );
816 
817  /* Fail if result was all zeros (as required by RFC8422) */
818  return ( bigint_is_zero ( &point.value ) ? -EPERM : 0 );
819 }
static const void const void void * result
Definition: crypto.h:335
An X25519 unsigned 257-bit integer.
Definition: x25519.h:64
static const void const void * scalar
Definition: crypto.h:335
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:50
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:118
static const void * base
Base address.
Definition: crypto.h:335
unsigned long tmp
Definition: linux_pci.h:53
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static void x25519_ladder(const union x25519_quad257 *base, struct x25519_value *scalar, union x25519_quad257 *result)
Multiply X25519 elliptic curve point.
Definition: x25519.c:738
static void x25519_reverse(struct x25519_value *value)
Reverse X25519 value endianness.
Definition: x25519.c:772
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:63
#define EPERM
Operation not permitted.
Definition: errno.h:614
An X25519 32-byte value.
Definition: x25519.h:77

References base, bigint_done, bigint_init, bigint_is_zero, EPERM, memcpy(), result, scalar, tmp, x25519_quad257::value, x25519_ladder(), and x25519_reverse().

Referenced by x25519_curve_multiply(), and x25519_key_okx().

◆ x25519_curve_multiply()

static int x25519_curve_multiply ( const void *  base,
const void *  scalar,
void *  result 
)
static

Multiply scalar by curve point.

Parameters
baseBase point (or NULL to use generator)
scalarScalar multiple
resultResult point to fill in
Return values
rcReturn status code

Definition at line 829 of file x25519.c.

830  {
831 
832  /* Use base point if applicable */
833  if ( ! base )
835 
836  return x25519_key ( base, scalar, result );
837 }
int x25519_key(const struct x25519_value *base, const struct x25519_value *scalar, struct x25519_value *result)
Calculate X25519 key.
Definition: x25519.c:793
static const void const void void * result
Definition: crypto.h:335
static const void const void * scalar
Definition: crypto.h:335
static const void * base
Base address.
Definition: crypto.h:335
static struct x25519_value x25519_generator
Constant g=9 (the group generator)
Definition: x25519.c:305

References base, result, scalar, x25519_generator, and x25519_key().

Variable Documentation

◆ __attribute__

◆ x25519_p_raw

const uint8_t x25519_p_raw[]
static
Initial value:
= {
0x7f, 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, 0xed
}

Constant p=2^255-19 (the finite field prime)

Definition at line 275 of file x25519.c.

Referenced by x25519_init_constants().

◆ x25519_p

x25519_t x25519_p
static

Constant p=2^255-19 (the finite field prime)

Definition at line 283 of file x25519.c.

Referenced by x25519_init_constants(), and x25519_reduce().

◆ x25519_2p

x25519_t x25519_2p
static

Constant 2p=2^256-38.

Definition at line 286 of file x25519.c.

Referenced by x25519_init_constants(), and x25519_reduce().

◆ x25519_4p

x25519_t x25519_4p
static

Constant 4p=2^257-76.

Definition at line 289 of file x25519.c.

Referenced by x25519_init_constants(), and x25519_subtract().

◆ x25519_reduce_256_raw

const uint8_t x25519_reduce_256_raw[] = { X25519_REDUCE_256 }
static

Reduction constant (used during multiplication)

Definition at line 292 of file x25519.c.

Referenced by x25519_init_constants().

◆ x25519_121665

union x25519_oct258 x25519_121665
static

Constant 121665 (used in the Montgomery ladder)

Definition at line 302 of file x25519.c.

Referenced by x25519_init_constants(), and x25519_step().

◆ x25519_generator

struct x25519_value x25519_generator
static
Initial value:
= {
.raw = { 9, }
}

Constant g=9 (the group generator)

Definition at line 305 of file x25519.c.

Referenced by x25519_curve_multiply().

◆ x25519_curve

struct elliptic_curve x25519_curve
Initial value:
= {
.name = "x25519",
.keysize = sizeof ( struct x25519_value ),
.multiply = x25519_curve_multiply,
}
static int x25519_curve_multiply(const void *base, const void *scalar, void *result)
Multiply scalar by curve point.
Definition: x25519.c:829
An X25519 32-byte value.
Definition: x25519.h:77

X25519 elliptic curve.

Definition at line 840 of file x25519.c.