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)
 
 FILE_SECBOOT (PERMITTED)
 
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...
 
void x25519_key (const struct x25519_value *base, const struct x25519_value *scalar, struct x25519_value *result)
 Calculate X25519 key. More...
 
int x25519_is_zero (const struct x25519_value *value)
 Check if X25519 value is zero. 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 27 of file x25519.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

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

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

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

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

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

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

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

◆ x25519_key()

void 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)

Definition at line 808 of file x25519.c.

810  {
811  struct x25519_value *tmp = result;
812  union x25519_quad257 point;
813 
814  /* Reverse base point and clear high bit as required by RFC7748 */
815  memcpy ( tmp, base, sizeof ( *tmp ) );
816  x25519_reverse ( tmp );
817  tmp->raw[0] &= 0x7f;
818  bigint_init ( &point.value, tmp->raw, sizeof ( tmp->raw ) );
819 
820  /* Clamp scalar as required by RFC7748 */
821  memcpy ( tmp, scalar, sizeof ( *tmp ) );
822  tmp->raw[0] &= 0xf8;
823  tmp->raw[31] |= 0x40;
824 
825  /* Multiply elliptic curve point */
826  x25519_ladder ( &point, tmp, &point );
827 
828  /* Reverse result */
829  bigint_done ( &point.value, result->raw, sizeof ( result->raw ) );
831 }
uint32_t base
Base.
Definition: librm.h:138
An X25519 unsigned 257-bit integer.
Definition: x25519.h:65
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
unsigned long tmp
Definition: linux_pci.h:65
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:740
static void x25519_reverse(struct x25519_value *value)
Reverse X25519 value endianness.
Definition: x25519.c:774
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:75
uint16_t result
Definition: hyperv.h:33
An X25519 32-byte value.
Definition: x25519.h:78

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

Referenced by x25519_curve_multiply(), and x25519_key_okx().

◆ x25519_is_zero()

int x25519_is_zero ( const struct x25519_value value)

Check if X25519 value is zero.

Parameters
valueValue to check
Return values
is_zeroValue is zero

Definition at line 793 of file x25519.c.

793  {
794  x25519_t point;
795 
796  /* Check if value is zero */
797  bigint_init ( &point, value->raw, sizeof ( value->raw ) );
798  return bigint_is_zero ( &point );
799 }
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:134
pseudo_bit_t value[0x00020]
Definition: arbel.h:13

References bigint_init, bigint_is_zero, and value.

Referenced by x25519_curve_is_infinity(), and x25519_key_okx().

Variable Documentation

◆ x25519_curve

struct elliptic_curve x25519_curve

X25519 elliptic curve.

Definition at line 876 of file x25519.c.