[crypto] Allow for addition of arbitrary Weierstrass curve points

ECDSA verification requires the ability to add two arbitrary curve
points (as well as the ability to multiply a curve point by a scalar).

Add an elliptic curve method to perform arbitrary point addition.
Pass in curve points as affine coordinates: this will require some
redundant conversions between affine coorfinates and the internal
representation as projective coordinates in Montgomery form, but keeps
the API as simple as possible.  Since we do not expect to perform a
high volume of ECDSA signature verifications, these redundant
calculations are an acceptable cost for keeping the code simple.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2025-12-06 16:59:29 +00:00
parent 1e353ff361
commit c7f129fede
8 changed files with 363 additions and 2 deletions

View File

@@ -194,6 +194,14 @@ struct elliptic_curve {
*/
int ( * multiply ) ( const void *base, const void *scalar,
void *result );
/** Add curve points (as a one-off operation)
*
* @v addend Curve point to add
* @v augend Curve point to add
* @v result Curve point to hold result
* @ret rc Return status code
*/
int ( * add ) ( const void *addend, const void *augend, void *result );
};
static inline __attribute__ (( always_inline )) void
@@ -305,6 +313,12 @@ elliptic_multiply ( struct elliptic_curve *curve,
return curve->multiply ( base, scalar, result );
}
static inline __attribute__ (( always_inline )) int
elliptic_add ( struct elliptic_curve *curve, const void *addend,
const void *augend, void *result ) {
return curve->add ( addend, augend, result );
}
extern void digest_null_init ( void *ctx );
extern void digest_null_update ( void *ctx, const void *src, size_t len );
extern void digest_null_final ( void *ctx, void *out );

View File

@@ -126,6 +126,9 @@ struct weierstrass_curve {
extern int weierstrass_multiply ( struct weierstrass_curve *curve,
const void *base, const void *scalar,
void *result );
extern int weierstrass_add_once ( struct weierstrass_curve *curve,
const void *addend, const void *augend,
void *result );
/** Define a Weierstrass curve */
#define WEIERSTRASS_CURVE( _name, _curve, _len, _prime, _a, _b, _base, \
@@ -157,6 +160,11 @@ extern int weierstrass_multiply ( struct weierstrass_curve *curve,
return weierstrass_multiply ( &_name ## _weierstrass, \
base, scalar, result ); \
} \
static int _name ## _add ( const void *addend, \
const void *augend, void *result) { \
return weierstrass_add_once ( &_name ## _weierstrass, \
addend, augend, result ); \
} \
struct elliptic_curve _curve = { \
.name = #_name, \
.pointsize = ( WEIERSTRASS_AXES * (_len) ), \
@@ -164,6 +172,7 @@ extern int weierstrass_multiply ( struct weierstrass_curve *curve,
.base = (_base), \
.order = (_order), \
.multiply = _name ## _multiply, \
.add = _name ## _add, \
}
#endif /* _IPXE_WEIERSTRASS_H */