mirror of https://github.com/ipxe/ipxe.git
167 lines
4.8 KiB
C
167 lines
4.8 KiB
C
#ifndef _IPXE_WEIERSTRASS_H
|
|
#define _IPXE_WEIERSTRASS_H
|
|
|
|
/** @file
|
|
*
|
|
* Weierstrass elliptic curves
|
|
*
|
|
*/
|
|
|
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|
|
|
#include <ipxe/bigint.h>
|
|
#include <ipxe/crypto.h>
|
|
|
|
/** Number of axes in Weierstrass curve point representation */
|
|
#define WEIERSTRASS_AXES 2
|
|
|
|
/**
|
|
* Maximum multiple of field prime encountered during calculations
|
|
*
|
|
* Calculations are performed using values modulo a small multiple of
|
|
* the field prime, rather than modulo the field prime itself. This
|
|
* allows explicit reductions after additions, subtractions, and
|
|
* relaxed Montgomery multiplications to be omitted entirely, provided
|
|
* that we keep careful track of the field prime multiple for each
|
|
* intermediate value.
|
|
*
|
|
* Relaxed Montgomery multiplication will produce a result in the
|
|
* range t < (1+m/k)N, where m is this maximum multiple of the field
|
|
* prime, and k is the constant in R > kN representing the leading
|
|
* zero padding in the big integer representation of the field prime.
|
|
* We choose to set k=m so that multiplications will always produce a
|
|
* result in the range t < 2N.
|
|
*
|
|
* This is expressed as the base-two logarithm of the multiple
|
|
* (rounded up), to simplify compile-time calculations.
|
|
*/
|
|
#define WEIERSTRASS_MAX_MULTIPLE_LOG2 5 /* maximum reached is mod 20N */
|
|
|
|
/**
|
|
* Determine number of elements in scalar values for a Weierstrass curve
|
|
*
|
|
* @v len Length of field prime, in bytes
|
|
* @ret size Number of elements
|
|
*/
|
|
#define weierstrass_size( len ) \
|
|
bigint_required_size ( (len) + \
|
|
( ( WEIERSTRASS_MAX_MULTIPLE_LOG2 + 7 ) \
|
|
/ 8 ) )
|
|
|
|
/**
|
|
* Define a Weierstrass projective co-ordinate type
|
|
*
|
|
* @v size Number of elements in scalar values
|
|
* @ret weierstrass_t Projective co-ordinate type
|
|
*/
|
|
#define weierstrass_t( size ) \
|
|
union { \
|
|
bigint_t ( size ) axis[3]; \
|
|
struct { \
|
|
bigint_t ( size ) x; \
|
|
bigint_t ( size ) y; \
|
|
bigint_t ( size ) z; \
|
|
}; \
|
|
bigint_t ( size * 3 ) all; \
|
|
}
|
|
|
|
/** Indexes for stored multiples of the field prime */
|
|
enum weierstrass_multiple {
|
|
WEIERSTRASS_N = 0,
|
|
WEIERSTRASS_2N,
|
|
WEIERSTRASS_4N,
|
|
WEIERSTRASS_NUM_MULTIPLES
|
|
};
|
|
|
|
/** Number of cached in Montgomery form for each Weierstrass curve */
|
|
#define WEIERSTRASS_NUM_MONT 3
|
|
|
|
/** Number of cached big integers for each Weierstrass curve */
|
|
#define WEIERSTRASS_NUM_CACHED \
|
|
( WEIERSTRASS_NUM_MULTIPLES + \
|
|
1 /* fermat */ + 1 /* mont */ + \
|
|
WEIERSTRASS_NUM_MONT )
|
|
|
|
/**
|
|
* A Weierstrass elliptic curve
|
|
*
|
|
* This is an elliptic curve y^2 = x^3 + ax + b
|
|
*/
|
|
struct weierstrass_curve {
|
|
/** Number of elements in scalar values */
|
|
const unsigned int size;
|
|
/** Curve name */
|
|
const char *name;
|
|
/** Length of raw scalar values */
|
|
size_t len;
|
|
/** Field prime */
|
|
const uint8_t *prime_raw;
|
|
/** Constant "a" */
|
|
const uint8_t *a_raw;
|
|
/** Constant "b" */
|
|
const uint8_t *b_raw;
|
|
/** Base point */
|
|
const uint8_t *base;
|
|
|
|
/** Cached field prime "N" (and multiples thereof) */
|
|
bigint_element_t *prime[WEIERSTRASS_NUM_CACHED];
|
|
/** Cached constant "N-2" (for Fermat's little theorem) */
|
|
bigint_element_t *fermat;
|
|
/** Cached Montgomery constant (R^2 mod N) */
|
|
bigint_element_t *square;
|
|
/** Cached constants in Montgomery form */
|
|
union {
|
|
struct {
|
|
/** Cached constant "1", in Montgomery form */
|
|
bigint_element_t *one;
|
|
/** Cached constant "a", in Montgomery form */
|
|
bigint_element_t *a;
|
|
/** Cached constant "3b", in Montgomery form */
|
|
bigint_element_t *b3;
|
|
};
|
|
bigint_element_t *mont[WEIERSTRASS_NUM_MONT];
|
|
};
|
|
};
|
|
|
|
extern int weierstrass_multiply ( struct weierstrass_curve *curve,
|
|
const void *base, const void *scalar,
|
|
void *result );
|
|
|
|
/** Define a Weierstrass curve */
|
|
#define WEIERSTRASS_CURVE( _name, _curve, _len, _prime, _a, _b, _base ) \
|
|
static bigint_t ( weierstrass_size(_len) ) \
|
|
_name ## _cache[WEIERSTRASS_NUM_CACHED]; \
|
|
static struct weierstrass_curve _name ## _weierstrass = { \
|
|
.size = weierstrass_size(_len), \
|
|
.name = #_name, \
|
|
.len = (_len), \
|
|
.prime_raw = (_prime), \
|
|
.a_raw = (_a), \
|
|
.b_raw = (_b), \
|
|
.base = (_base), \
|
|
.prime = { \
|
|
(_name ## _cache)[0].element, \
|
|
(_name ## _cache)[1].element, \
|
|
(_name ## _cache)[2].element, \
|
|
}, \
|
|
.fermat = (_name ## _cache)[3].element, \
|
|
.square = (_name ## _cache)[4].element, \
|
|
.one = (_name ## _cache)[5].element, \
|
|
.a = (_name ## _cache)[6].element, \
|
|
.b3 = (_name ## _cache)[7].element, \
|
|
}; \
|
|
static int _name ## _multiply ( const void *base, \
|
|
const void *scalar, \
|
|
void *result ) { \
|
|
return weierstrass_multiply ( &_name ## _weierstrass, \
|
|
base, scalar, result ); \
|
|
} \
|
|
struct elliptic_curve _curve = { \
|
|
.name = #_name, \
|
|
.pointsize = ( WEIERSTRASS_AXES * (_len) ), \
|
|
.keysize = (_len), \
|
|
.multiply = _name ## _multiply, \
|
|
}
|
|
|
|
#endif /* _IPXE_WEIERSTRASS_H */
|