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

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static bigint_t (bigint_required_size(sizeof(x25519_reduce_256_raw)))
 Reduction constant (used during multiplication)
static void x25519_init_constants (void)
 Initialise constants.
struct init_fn x25519_init_fn __init_fn (INIT_NORMAL)
 Initialisation function.
static void x25519_add (const union x25519_quad257 *augend, const union x25519_quad257 *addend, union x25519_oct258 *result)
 Add big integers modulo field prime.
static void x25519_subtract (const union x25519_quad257 *minuend, const union x25519_quad257 *subtrahend, union x25519_oct258 *result)
 Subtract big integers modulo field prime.
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.
static void x25519_reduce_by (const x25519_t *subtrahend, x25519_t *value)
 Reduce big integer via conditional subtraction.
void x25519_reduce (union x25519_quad257 *value)
 Reduce big integer to canonical range.
static void x25519_step (const union x25519_quad257 *base, int bit, struct x25519_step *step)
 Compute next step of the Montgomery ladder.
static void x25519_ladder (const union x25519_quad257 *base, struct x25519_value *scalar, union x25519_quad257 *result)
 Multiply X25519 elliptic curve point.
static void x25519_reverse (struct x25519_value *value)
 Reverse X25519 value endianness.
int x25519_is_zero (const struct x25519_value *value)
 Check if X25519 value is zero.
void x25519_key (const struct x25519_value *base, const struct x25519_value *scalar, struct x25519_value *result)
 Calculate X25519 key.
static int x25519_curve_is_infinity (const void *point)
 Check if this is the point at infinity.
static int x25519_curve_multiply (const void *base, const void *scalar, void *result)
 Multiply scalar by curve point.
static int x25519_curve_add (const void *addend __unused, const void *augend __unused, void *result __unused)
 Add curve points (as a one-off operation)

Variables

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

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

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ bigint_t()

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

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

References bigint_required_size, and x25519_reduce_256_raw.

◆ x25519_init_constants()

void x25519_init_constants ( void )
static

Initialise constants.

Definition at line 314 of file x25519.c.

314 {
315
316 /* Construct constant p */
318
319 /* Construct constant 2p */
322
323 /* Construct constant 4p */
326
327 /* Construct reduction constant */
328 bigint_init ( &x25519_reduce_256, x25519_reduce_256_raw,
329 sizeof ( x25519_reduce_256_raw ) );
330
331 /* Construct constant 121665 */
332 bigint_init ( &x25519_121665.value, x25519_121665_raw,
333 sizeof ( x25519_121665_raw ) );
334}
#define bigint_copy(source, dest)
Copy big integer.
Definition bigint.h:235
#define bigint_add(addend, value)
Add big integers.
Definition bigint.h:87
#define bigint_init(value, data, len)
Initialise big integer.
Definition bigint.h:62
static const uint8_t x25519_p_raw[]
Constant p=2^255-19 (the finite field prime)
Definition x25519.c:276
static x25519_t x25519_2p
Constant 2p=2^256-38.
Definition x25519.c:287
static x25519_t x25519_4p
Constant 4p=2^257-76.
Definition x25519.c:290
static union x25519_oct258 x25519_121665
Constant 121665 (used in the Montgomery ladder)
Definition x25519.c:303
static const uint8_t x25519_reduce_256_raw[]
Reduction constant (used during multiplication)
Definition x25519.c:293
static x25519_t x25519_p
Constant p=2^255-19 (the finite field prime)
Definition x25519.c:284

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

Referenced by __init_fn().

◆ __init_fn()

struct init_fn x25519_init_fn __init_fn ( INIT_NORMAL )

Initialisation function.

References __init_fn, INIT_NORMAL, and x25519_init_constants().

◆ x25519_add()

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

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

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

Referenced by x25519_step().

◆ x25519_subtract()

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

385 {
386 int copy;
387
388 /* Copy minuend if necessary */
389 copy = ( result != &minuend->oct258 );
390 build_assert ( __builtin_constant_p ( copy ) );
391 if ( copy ) {
392 build_assert ( result != &subtrahend->oct258 );
393 bigint_copy ( &minuend->oct258.value, &result->value );
394 }
395
396 /* Perform subtraction
397 *
398 * Both inputs are in the range [0,4p-1] and the resulting
399 * difference is therefore in the range [1-4p,4p-1].
400 *
401 * This range lies partially outside the range [0,8p-1] and
402 * the result is therefore not yet a valid X25519 unsigned
403 * 258-bit integer.
404 */
405 bigint_subtract ( &subtrahend->value, &result->value );
406
407 /* Add constant multiple of field prime p
408 *
409 * Add the constant 4p to the result. This brings the result
410 * within the range [1,8p-1] (without changing the value
411 * modulo p).
412 *
413 * This range lies within the range [0,8p-1] and the result is
414 * therefore now a valid X25519 unsigned 258-bit integer, as
415 * required.
416 */
417 bigint_add ( &x25519_4p, &result->value );
418}
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition bigint.h:99

References bigint_add, bigint_copy, bigint_subtract, build_assert, x25519_quad257::oct258, result, x25519_oct258::value, x25519_quad257::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 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}
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
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

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 )

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

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

567 {
568 x25519_t tmp;
569 int underflow;
570
571 /* Conditionally subtract subtrahend
572 *
573 * Subtract the subtrahend, discarding the result (in constant
574 * time) if the subtraction underflows.
575 */
576 bigint_copy ( value, &tmp );
577 underflow = bigint_subtract ( subtrahend, value );
578 bigint_swap ( value, &tmp, underflow );
579}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
#define bigint_swap(first, second, swap)
Conditionally swap big integers (in constant time)
Definition bigint.h:247

References bigint_copy, bigint_subtract, bigint_swap, 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 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 void x25519_reduce_by(const x25519_t *subtrahend, x25519_t *value)
Reduce big integer via conditional subtraction.
Definition x25519.c:567

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

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

◆ x25519_step()

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

619 {
620 union x25519_quad257 *a = &step->x_n.X;
621 union x25519_quad257 *b = &step->x_n1.X;
622 union x25519_quad257 *c = &step->x_n.Z;
623 union x25519_quad257 *d = &step->x_n1.Z;
624 union x25519_oct258 e;
625 union x25519_quad257 f;
626 union x25519_oct258 *v1_e;
627 union x25519_oct258 *v2_a;
628 union x25519_oct258 *v3_c;
629 union x25519_oct258 *v4_b;
630 union x25519_quad257 *v5_d;
631 union x25519_quad257 *v6_f;
632 union x25519_quad257 *v7_a;
633 union x25519_quad257 *v8_c;
634 union x25519_oct258 *v9_e;
635 union x25519_oct258 *v10_a;
636 union x25519_quad257 *v11_b;
637 union x25519_oct258 *v12_c;
638 union x25519_quad257 *v13_a;
639 union x25519_oct258 *v14_a;
640 union x25519_quad257 *v15_c;
641 union x25519_quad257 *v16_a;
642 union x25519_quad257 *v17_d;
643 union x25519_quad257 *v18_b;
644
645 /* See the referenced paper "Implementing Curve25519/X25519: A
646 * Tutorial on Elliptic Curve Cryptography" for the reasoning
647 * behind this calculation.
648 */
649
650 /* Reuse storage locations for intermediate results where possible */
651 v1_e = &e;
652 v2_a = container_of ( &a->value, union x25519_oct258, value );
653 v3_c = container_of ( &c->value, union x25519_oct258, value );
654 v4_b = container_of ( &b->value, union x25519_oct258, value );
655 v5_d = d;
656 v6_f = &f;
657 v7_a = a;
658 v8_c = c;
659 v9_e = &e;
660 v10_a = container_of ( &a->value, union x25519_oct258, value );
661 v11_b = b;
662 v12_c = container_of ( &c->value, union x25519_oct258, value );
663 v13_a = a;
664 v14_a = container_of ( &a->value, union x25519_oct258, value );
665 v15_c = c;
666 v16_a = a;
667 v17_d = d;
668 v18_b = b;
669
670 /* Select inputs */
671 bigint_swap ( &a->value, &b->value, bit );
672 bigint_swap ( &c->value, &d->value, bit );
673
674 /* v1 = a + c */
675 x25519_add ( a, c, v1_e );
676
677 /* v2 = a - c */
678 x25519_subtract ( a, c, v2_a );
679
680 /* v3 = b + d */
681 x25519_add ( b, d, v3_c );
682
683 /* v4 = b - d */
684 x25519_subtract ( b, d, v4_b );
685
686 /* v5 = v1^2 = (a + c)^2 = a^2 + 2ac + c^2 */
687 x25519_multiply ( v1_e, v1_e, v5_d );
688
689 /* v6 = v2^2 = (a - c)^2 = a^2 - 2ac + c^2 */
690 x25519_multiply ( v2_a, v2_a, v6_f );
691
692 /* v7 = v3 * v2 = (b + d) * (a - c) = ab - bc + ad - cd */
693 x25519_multiply ( v3_c, v2_a, v7_a );
694
695 /* v8 = v4 * v1 = (b - d) * (a + c) = ab + bc - ad - cd */
696 x25519_multiply ( v4_b, v1_e, v8_c );
697
698 /* v9 = v7 + v8 = 2 * (ab - cd) */
699 x25519_add ( v7_a, v8_c, v9_e );
700
701 /* v10 = v7 - v8 = 2 * (ad - bc) */
702 x25519_subtract ( v7_a, v8_c, v10_a );
703
704 /* v11 = v10^2 = 4 * (ad - bc)^2 */
705 x25519_multiply ( v10_a, v10_a, v11_b );
706
707 /* v12 = v5 - v6 = (a + c)^2 - (a - c)^2 = 4ac */
708 x25519_subtract ( v5_d, v6_f, v12_c );
709
710 /* v13 = v12 * 121665 = 486660ac = (A-2) * ac */
711 x25519_multiply ( v12_c, &x25519_121665, v13_a );
712
713 /* v14 = v13 + v5 = (A-2) * ac + a^2 + 2ac + c^2 = a^2 + A * ac + c^2 */
714 x25519_add ( v13_a, v5_d, v14_a );
715
716 /* v15 = v12 * v14 = 4ac * (a^2 + A * ac + c^2) */
717 x25519_multiply ( v12_c, v14_a, v15_c );
718
719 /* v16 = v5 * v6 = (a + c)^2 * (a - c)^2 = (a^2 - c^2)^2 */
720 x25519_multiply ( &v5_d->oct258, &v6_f->oct258, v16_a );
721
722 /* v17 = v11 * base = 4 * base * (ad - bc)^2 */
723 x25519_multiply ( &v11_b->oct258, &base->oct258, v17_d );
724
725 /* v18 = v9^2 = 4 * (ab - cd)^2 */
726 x25519_multiply ( v9_e, v9_e, v18_b );
727
728 /* Select outputs */
729 bigint_swap ( &a->value, &b->value, bit );
730 bigint_swap ( &c->value, &d->value, bit );
731}
static unsigned int unsigned int bit
Definition bigint.h:392
uint32_t base
Base.
Definition librm.h:3
void step(void)
Single-step a single process.
Definition process.c:99
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
An X25519 unsigned 258-bit integer.
Definition x25519.h:46
An X25519 unsigned 257-bit integer.
Definition x25519.h:65
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:350
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:383

References base, bigint_swap, bit, container_of, x25519_quad257::oct258, step(), value, x25519_quad257::value, x25519_121665, x25519_add(), x25519_multiply(), and x25519_subtract().

Referenced by x25519_ladder().

◆ x25519_ladder()

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

742 {
743 static const uint8_t zero[] = { 0 };
744 static const uint8_t one[] = { 1 };
745 struct x25519_step step;
746 union x25519_quad257 *tmp;
747 int bit;
748 int i;
749
750 /* Initialise ladder */
751 bigint_init ( &step.x_n.X.value, one, sizeof ( one ) );
752 bigint_init ( &step.x_n.Z.value, zero, sizeof ( zero ) );
753 bigint_copy ( &base->value, &step.x_n1.X.value );
754 bigint_init ( &step.x_n1.Z.value, one, sizeof ( one ) );
755
756 /* Use ladder */
757 for ( i = 254 ; i >= 0 ; i-- ) {
758 bit = ( ( scalar->raw[ i / 8 ] >> ( i % 8 ) ) & 1 );
759 x25519_step ( base, bit, &step );
760 }
761
762 /* Convert back to affine coordinate */
763 tmp = &step.x_n1.X;
764 x25519_invert ( &step.x_n.Z.oct258, tmp );
765 x25519_multiply ( &step.x_n.X.oct258, &tmp->oct258, result );
767}
unsigned char uint8_t
Definition stdint.h:10
An X25519 Montgomery ladder step.
Definition x25519.c:268
uint8_t raw[32]
Raw value.
Definition x25519.h:80
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:618
void x25519_reduce(union x25519_quad257 *value)
Reduce big integer to canonical range.
Definition x25519.c:586
void x25519_invert(const union x25519_oct258 *invertend, union x25519_quad257 *result)
Compute multiplicative inverse.
Definition x25519.c:529

References base, bigint_copy, bigint_init, bit, x25519_value::raw, result, step(), tmp, x25519_invert(), x25519_multiply(), x25519_reduce(), and x25519_step().

Referenced by x25519_key().

◆ x25519_reverse()

void x25519_reverse ( struct x25519_value * value)
static

Reverse X25519 value endianness.

Parameters
valueValue to reverse

Definition at line 774 of file x25519.c.

774 {
775 uint8_t *low = value->raw;
776 uint8_t *high = &value->raw[ sizeof ( value->raw ) - 1 ];
777 uint8_t tmp;
778
779 /* Reverse bytes */
780 do {
781 tmp = *low;
782 *low = *high;
783 *high = tmp;
784 } while ( ++low < --high );
785}
uint32_t high
High 32 bits of address.
Definition myson.h:1
uint32_t low
Low 16 bits of address.
Definition myson.h:0

References high, low, tmp, and value.

Referenced by x25519_key().

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

◆ 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 ) );
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
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An X25519 32-byte value.
Definition x25519.h:78
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_curve_is_infinity()

int x25519_curve_is_infinity ( const void * point)
static

Check if this is the point at infinity.

Parameters
pointCurve point
Return values
is_infinityThis is the point at infinity

Definition at line 839 of file x25519.c.

839 {
840
841 /* We use all zeroes for the point at infinity (as per RFC8422) */
842 return x25519_is_zero ( point );
843}
int x25519_is_zero(const struct x25519_value *value)
Check if X25519 value is zero.
Definition x25519.c:793

References x25519_is_zero().

◆ x25519_curve_multiply()

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

Multiply scalar by curve point.

Parameters
baseBase point
scalarScalar multiple
resultResult point to fill in
Return values
rcReturn status code

Definition at line 853 of file x25519.c.

854 {
855
856 x25519_key ( base, scalar, result );
857 return 0;
858}
void x25519_key(const struct x25519_value *base, const struct x25519_value *scalar, struct x25519_value *result)
Calculate X25519 key.
Definition x25519.c:808

References base, result, and x25519_key().

◆ x25519_curve_add()

int x25519_curve_add ( const void *addend __unused,
const void *augend __unused,
void *result __unused )
static

Add curve points (as a one-off operation)

Parameters
addendCurve point to add
augendCurve point to add
resultCurve point to hold result
Return values
rcReturn status code

Definition at line 868 of file x25519.c.

870 {
871
872 return -ENOTTY;
873}
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595

References __unused, ENOTTY, and result.

Variable Documentation

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

276 {
277 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
278 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
279 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
280 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xed
281};

Referenced by x25519_init_constants().

◆ x25519_p

x25519_t x25519_p
static

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

Definition at line 284 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 287 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 290 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 293 of file x25519.c.

#define X25519_REDUCE_256
X25519 reduction constant.
Definition x25519.c:98

Referenced by bigint_t(), and x25519_init_constants().

◆ x25519_121665

union x25519_oct258 x25519_121665
static

Constant 121665 (used in the Montgomery ladder)

Definition at line 303 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 306 of file x25519.c.

306 {
307 .raw = { 9, }
308};

◆ x25519_curve

struct elliptic_curve x25519_curve
Initial value:
= {
.name = "x25519",
.pointsize = sizeof ( struct x25519_value ),
.keysize = sizeof ( struct x25519_value ),
.is_infinity = x25519_curve_is_infinity,
.multiply = x25519_curve_multiply,
}
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

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};

Referenced by __tls_named_curve().