iPXE
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.

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.
void x25519_multiply (const union x25519_oct258 *multiplicand, const union x25519_oct258 *multiplier, union x25519_quad257 *result)
 Multiply big integers modulo field prime.
void x25519_invert (const union x25519_oct258 *invertend, union x25519_quad257 *result)
 Compute multiplicative inverse.
void x25519_reduce (union x25519_quad257 *value)
 Reduce big integer to canonical range.
void x25519_key (const struct x25519_value *base, const struct x25519_value *scalar, struct x25519_value *result)
 Calculate X25519 key.
int x25519_is_zero (const struct x25519_value *value)
 Check if X25519 value is zero.

Variables

struct elliptic_curve x25519_curve
 X25519 elliptic curve.

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.

Referenced by bigint_t(), and x25519_multiply_step1::bigint_t().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ bigint_t()

typedef bigint_t ( X25519_SIZE )

An X25519 unsigned big integer used in internal calculations.

References X25519_SIZE.

◆ x25519_multiply()

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

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}
uint16_t result
Definition hyperv.h:33
static const uint32_t multiplier
Port multiplier number.
Definition bigint.h:335
#define bigint_grow(source, dest)
Grow big integer.
Definition bigint.h:209
#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
void * memset(void *dest, int character, size_t len) __nonnull
unsigned long tmp
Definition linux_pci.h:65
X25519 multiplication step 1 result.
Definition x25519.c:108
struct x25519_multiply_step1::@143326331223017073312237123340004167004022061343 parts
Partition into low-order and high-order bits.
X25519 multiplication step 2 result.
Definition x25519.c:145
X25519 multiplication step 3 result.
Definition x25519.c:189
X25519 multiplication temporary working space.
Definition x25519.c:217
x25519_t value
Big integer value.
Definition x25519.h:48

References bigint_add, bigint_grow, bigint_multiply, memset(), multiplier, x25519_multiply_step1::parts, x25519_multiply_step2::parts, result, 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 )
extern

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}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define bigint_copy(source, dest)
Copy big integer.
Definition bigint.h:235
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

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

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}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
static void x25519_reduce_by(const x25519_t *subtrahend, x25519_t *value)
Reduce big integer via conditional subtraction.
Definition x25519.c:567
static x25519_t x25519_2p
Constant 2p=2^256-38.
Definition x25519.c:287
static x25519_t x25519_p
Constant p=2^255-19 (the finite field prime)
Definition x25519.c:284

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

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 ) );
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}
#define bigint_done(value, out, len)
Finalise big integer.
Definition bigint.h:75
#define bigint_init(value, data, len)
Initialise big integer.
Definition bigint.h:62
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint32_t base
Base.
Definition librm.h:3
An X25519 32-byte value.
Definition x25519.h:78
An X25519 unsigned 257-bit integer.
Definition x25519.h:65
static void x25519_reverse(struct x25519_value *value)
Reverse X25519 value endianness.
Definition x25519.c:774
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

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

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_is_zero(value)
Test if big integer is equal to zero.
Definition bigint.h:134

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
extern

X25519 elliptic curve.

Definition at line 876 of file x25519.c.

876 {
877 .name = "x25519",
878 .pointsize = sizeof ( struct x25519_value ),
879 .keysize = sizeof ( struct x25519_value ),
880 .base = x25519_generator.raw,
881 .is_infinity = x25519_curve_is_infinity,
882 .multiply = x25519_curve_multiply,
883 .add = x25519_curve_add,
884};
u16 keysize
Length of encryption key to be used, network byte order.
Definition wpa.h:10
static struct x25519_value x25519_generator
Constant g=9 (the group generator)
Definition x25519.c:306
static int x25519_curve_is_infinity(const void *point)
Check if this is the point at infinity.
Definition x25519.c:839
static int x25519_curve_multiply(const void *base, const void *scalar, void *result)
Multiply scalar by curve point.
Definition x25519.c:853
static int x25519_curve_add(const void *addend __unused, const void *augend __unused, void *result __unused)
Add curve points (as a one-off operation)
Definition x25519.c:868

Referenced by __tls_named_curve().