[crypto] Expose the (prime) group order as an elliptic curve property

ECDSA requires knowledge of the group order of the base point, and is
defined only for curves with a prime group order (e.g. the NIST
curves).

Add the group order as an explicit property of an elliptic curve, and
add tests to verify that the order is correct.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-12-05 14:47:55 +00:00
parent 80e98dc0d1
commit d3adea8380
8 changed files with 82 additions and 3 deletions

View File

@@ -35,10 +35,53 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <ipxe/bigint.h>
#include <ipxe/crypto.h>
#include <ipxe/test.h>
#include "elliptic_test.h"
/**
* Report elliptic curve sanity test result
*
* @v curve Elliptic curve
* @v file Test code file
* @v line Test code line
*/
void elliptic_curve_okx ( struct elliptic_curve *curve, const char *file,
unsigned int line ) {
static const uint8_t one[] = { 1 };
size_t pointsize = curve->pointsize;
size_t keysize = curve->keysize;
uint8_t point[pointsize];
uint8_t scalar[keysize];
struct {
bigint_t ( bigint_required_size ( keysize ) ) scalar;
bigint_t ( bigint_required_size ( keysize ) ) one;
} temp;
/* Check that curve has the required properties */
okx ( curve->base != NULL, file, line );
okx ( curve->order != NULL, file, line );
/* Test multiplying base point by group order. Result should
* be the point at infinity, which should not be representable
* as a point in affine coordinates (and so should fail).
*/
okx ( elliptic_multiply ( curve, curve->base, curve->order,
point ) != 0, file, line );
/* Test multiplying base point by group order plus one, to get
* back to the base point.
*/
bigint_init ( &temp.scalar, curve->order, keysize );
bigint_init ( &temp.one, one, sizeof ( one ) );
bigint_add ( &temp.one, &temp.scalar );
bigint_done ( &temp.scalar, scalar, sizeof ( scalar ) );
okx ( elliptic_multiply ( curve, curve->base, scalar, point ) == 0,
file, line );
okx ( memcmp ( point, curve->base, pointsize ) == 0, file, line );
}
/**
* Report elliptic curve point multiplication test result
*

View File

@@ -64,9 +64,19 @@ struct elliptic_multiply_test {
.expected_len = sizeof ( name ## _expected ), \
};
extern void elliptic_curve_okx ( struct elliptic_curve *curve,
const char *file, unsigned int line );
extern void elliptic_multiply_okx ( struct elliptic_multiply_test *test,
const char *file, unsigned int line );
/**
* Report an elliptic curve sanity test result
*
* @v curve Elliptic curve
*/
#define elliptic_curve_ok( curve ) \
elliptic_curve_okx ( curve, __FILE__, __LINE__ )
/**
* Report an elliptic curve point multiplication test result
*

View File

@@ -157,6 +157,9 @@ ELLIPTIC_MULTIPLY_TEST ( invalid_one, &p256_curve,
*/
static void p256_test_exec ( void ) {
/* Curve sanity test */
elliptic_curve_ok ( &p256_curve );
/* Tests from http://point-at-infinity.org/ecc/nisttv */
elliptic_multiply_ok ( &poi_1 );
elliptic_multiply_ok ( &poi_2 );

View File

@@ -203,6 +203,9 @@ ELLIPTIC_MULTIPLY_TEST ( invalid_one, &p384_curve,
*/
static void p384_test_exec ( void ) {
/* Curve sanity test */
elliptic_curve_ok ( &p384_curve );
/* Tests from http://point-at-infinity.org/ecc/nisttv */
elliptic_multiply_ok ( &poi_1 );
elliptic_multiply_ok ( &poi_2 );