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

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_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().

Variable Documentation

◆ x25519_curve

struct elliptic_curve x25519_curve

X25519 elliptic curve.

Definition at line 840 of file x25519.c.