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

X25519 key exchange. More...

#include <stdint.h>
#include <ipxe/bigint.h>
#include <ipxe/crypto.h>

Go to the source code of this file.

Data Structures

union  x25519_oct258
 An X25519 unsigned 258-bit integer. More...
 
union  x25519_quad257
 An X25519 unsigned 257-bit integer. More...
 
struct  x25519_value
 An X25519 32-byte value. More...
 

Macros

#define X25519_SIZE   bigint_required_size ( ( 267 /* bits */ + 7 ) / 8 )
 X25519 unsigned big integer size. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
typedef bigint_t (X25519_SIZE) x25519_t
 An X25519 unsigned big integer used in internal calculations. 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...
 
void x25519_reduce (union x25519_quad257 *value)
 Reduce big integer to canonical range. More...
 
int x25519_key (const struct x25519_value *base, const struct x25519_value *scalar, struct x25519_value *result)
 Calculate X25519 key. More...
 

Variables

struct elliptic_curve x25519_curve
 X25519 elliptic curve. More...
 

Detailed Description

X25519 key exchange.

Definition in file x25519.h.

Macro Definition Documentation

◆ X25519_SIZE

#define X25519_SIZE   bigint_required_size ( ( 267 /* bits */ + 7 ) / 8 )

X25519 unsigned big integer size.

X25519 uses the finite field of integers modulo the prime p=2^255-19. The canonical representations of integers in this field therefore require only 255 bits.

For internal calculations we use big integers containing up to 267 bits, since this ends up allowing us to avoid some unnecessary (and expensive) intermediate reductions modulo p.

Definition at line 26 of file x25519.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ bigint_t()

typedef bigint_t ( X25519_SIZE  )

◆ 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 426 of file x25519.c.

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

529  {
530  int i;
531 
532  /* Sanity check */
533  assert ( invertend != &result->oct258 );
534 
535  /* Calculate inverse as x^(-1)=x^(p-2) where p is the field prime
536  *
537  * The field prime is p=2^255-19 and so:
538  *
539  * p - 2 = 2^255 - 21
540  * = (2^255 - 1) - 2^4 - 2^2
541  *
542  * i.e. p-2 is a 254-bit number in which all bits are set
543  * apart from bit 2 and bit 4.
544  *
545  * We use the square-and-multiply method to compute x^(p-2).
546  */
547  bigint_copy ( &invertend->value, &result->value );
548  for ( i = 253 ; i >= 0 ; i-- ) {
549 
550  /* Square running total */
551  x25519_multiply ( &result->oct258, &result->oct258, result );
552 
553  /* For each set bit in the exponent, multiply by invertend */
554  if ( ( i != 2 ) && ( i != 4 ) ) {
555  x25519_multiply ( invertend, &result->oct258, result );
556  }
557  }
558 }
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:426
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:234
uint16_t result
Definition: hyperv.h:33
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()

void x25519_reduce ( union x25519_quad257 value)

Reduce big integer to canonical range.

Parameters
valueBig integer to be reduced

Definition at line 585 of file x25519.c.

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

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

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

◆ 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 794 of file x25519.c.

796  {
797  struct x25519_value *tmp = result;
798  union x25519_quad257 point;
799 
800  /* Reverse base point and clear high bit as required by RFC7748 */
801  memcpy ( tmp, base, sizeof ( *tmp ) );
802  x25519_reverse ( tmp );
803  tmp->raw[0] &= 0x7f;
804  bigint_init ( &point.value, tmp->raw, sizeof ( tmp->raw ) );
805 
806  /* Clamp scalar as required by RFC7748 */
807  memcpy ( tmp, scalar, sizeof ( *tmp ) );
808  tmp->raw[0] &= 0xf8;
809  tmp->raw[31] |= 0x40;
810 
811  /* Multiply elliptic curve point */
812  x25519_ladder ( &point, tmp, &point );
813 
814  /* Reverse result */
815  bigint_done ( &point.value, result->raw, sizeof ( result->raw ) );
817 
818  /* Fail if result was all zeros (as required by RFC8422) */
819  return ( bigint_is_zero ( &point.value ) ? -EPERM : 0 );
820 }
uint32_t base
Base.
Definition: librm.h:138
An X25519 unsigned 257-bit integer.
Definition: x25519.h:64
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:61
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:133
unsigned long tmp
Definition: linux_pci.h:64
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:739
static void x25519_reverse(struct x25519_value *value)
Reverse X25519 value endianness.
Definition: x25519.c:773
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:74
#define EPERM
Operation not permitted.
Definition: errno.h:614
uint16_t result
Definition: hyperv.h:33
An X25519 32-byte value.
Definition: x25519.h:77

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

Referenced by x25519_curve_multiply(), and x25519_key_okx().

Variable Documentation

◆ x25519_curve

struct elliptic_curve x25519_curve

X25519 elliptic curve.

Definition at line 841 of file x25519.c.