iPXE
weierstrass.h
Go to the documentation of this file.
1 #ifndef _IPXE_WEIERSTRASS_H
2 #define _IPXE_WEIERSTRASS_H
3 
4 /** @file
5  *
6  * Weierstrass elliptic curves
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 FILE_SECBOOT ( PERMITTED );
12 
13 #include <ipxe/bigint.h>
14 #include <ipxe/crypto.h>
15 
16 /** Number of axes in Weierstrass curve point representation */
17 #define WEIERSTRASS_AXES 2
18 
19 /**
20  * Maximum multiple of field prime encountered during calculations
21  *
22  * Calculations are performed using values modulo a small multiple of
23  * the field prime, rather than modulo the field prime itself. This
24  * allows explicit reductions after additions, subtractions, and
25  * relaxed Montgomery multiplications to be omitted entirely, provided
26  * that we keep careful track of the field prime multiple for each
27  * intermediate value.
28  *
29  * Relaxed Montgomery multiplication will produce a result in the
30  * range t < (1+m/k)N, where m is this maximum multiple of the field
31  * prime, and k is the constant in R > kN representing the leading
32  * zero padding in the big integer representation of the field prime.
33  * We choose to set k=m so that multiplications will always produce a
34  * result in the range t < 2N.
35  *
36  * This is expressed as the base-two logarithm of the multiple
37  * (rounded up), to simplify compile-time calculations.
38  */
39 #define WEIERSTRASS_MAX_MULTIPLE_LOG2 5 /* maximum reached is mod 20N */
40 
41 /**
42  * Determine number of elements in scalar values for a Weierstrass curve
43  *
44  * @v len Length of field prime, in bytes
45  * @ret size Number of elements
46  */
47 #define weierstrass_size( len ) \
48  bigint_required_size ( (len) + \
49  ( ( WEIERSTRASS_MAX_MULTIPLE_LOG2 + 7 ) \
50  / 8 ) )
51 
52 /**
53  * Define a Weierstrass projective co-ordinate type
54  *
55  * @v size Number of elements in scalar values
56  * @ret weierstrass_t Projective co-ordinate type
57  */
58 #define weierstrass_t( size ) \
59  union { \
60  bigint_t ( size ) axis[3]; \
61  struct { \
62  bigint_t ( size ) x; \
63  bigint_t ( size ) y; \
64  bigint_t ( size ) z; \
65  }; \
66  bigint_t ( size * 2 ) xy; \
67  bigint_t ( size * 3 ) all; \
68  }
69 
70 /** Indexes for stored multiples of the field prime */
76 };
77 
78 /** Number of cached in Montgomery form for each Weierstrass curve */
79 #define WEIERSTRASS_NUM_MONT 3
80 
81 /** Number of cached big integers for each Weierstrass curve */
82 #define WEIERSTRASS_NUM_CACHED \
83  ( WEIERSTRASS_NUM_MULTIPLES + \
84  1 /* fermat */ + 1 /* mont */ + \
85  WEIERSTRASS_NUM_MONT )
86 
87 /**
88  * A Weierstrass elliptic curve
89  *
90  * This is an elliptic curve y^2 = x^3 + ax + b
91  */
93  /** Number of elements in scalar values */
94  const unsigned int size;
95  /** Curve name */
96  const char *name;
97  /** Length of raw scalar values */
98  size_t len;
99  /** Field prime */
101  /** Constant "a" */
102  const uint8_t *a_raw;
103  /** Constant "b" */
104  const uint8_t *b_raw;
105  /** Base point */
106  const uint8_t *base;
107 
108  /** Cached field prime "N" (and multiples thereof) */
110  /** Cached constant "N-2" (for Fermat's little theorem) */
112  /** Cached Montgomery constant (R^2 mod N) */
114  /** Cached constants in Montgomery form */
115  union {
116  struct {
117  /** Cached constant "1", in Montgomery form */
119  /** Cached constant "a", in Montgomery form */
121  /** Cached constant "3b", in Montgomery form */
123  };
125  };
126 };
127 
128 extern int weierstrass_is_infinity ( struct weierstrass_curve *curve,
129  const void *point );
130 extern int weierstrass_multiply ( struct weierstrass_curve *curve,
131  const void *base, const void *scalar,
132  void *result );
133 extern int weierstrass_add_once ( struct weierstrass_curve *curve,
134  const void *addend, const void *augend,
135  void *result );
136 
137 /** Define a Weierstrass curve */
138 #define WEIERSTRASS_CURVE( _name, _curve, _len, _prime, _a, _b, _base, \
139  _order ) \
140  static bigint_t ( weierstrass_size(_len) ) \
141  _name ## _cache[WEIERSTRASS_NUM_CACHED]; \
142  static struct weierstrass_curve _name ## _weierstrass = { \
143  .size = weierstrass_size(_len), \
144  .name = #_name, \
145  .len = (_len), \
146  .prime_raw = (_prime), \
147  .a_raw = (_a), \
148  .b_raw = (_b), \
149  .base = (_base), \
150  .prime = { \
151  (_name ## _cache)[0].element, \
152  (_name ## _cache)[1].element, \
153  (_name ## _cache)[2].element, \
154  }, \
155  .fermat = (_name ## _cache)[3].element, \
156  .square = (_name ## _cache)[4].element, \
157  .one = (_name ## _cache)[5].element, \
158  .a = (_name ## _cache)[6].element, \
159  .b3 = (_name ## _cache)[7].element, \
160  }; \
161  static int _name ## _is_infinity ( const void *point) { \
162  return weierstrass_is_infinity ( &_name ## _weierstrass,\
163  point ); \
164  } \
165  static int _name ## _multiply ( const void *base, \
166  const void *scalar, \
167  void *result ) { \
168  return weierstrass_multiply ( &_name ## _weierstrass, \
169  base, scalar, result ); \
170  } \
171  static int _name ## _add ( const void *addend, \
172  const void *augend, void *result) { \
173  return weierstrass_add_once ( &_name ## _weierstrass, \
174  addend, augend, result ); \
175  } \
176  struct elliptic_curve _curve = { \
177  .name = #_name, \
178  .pointsize = ( WEIERSTRASS_AXES * (_len) ), \
179  .keysize = (_len), \
180  .base = (_base), \
181  .order = (_order), \
182  .is_infinity = _name ## _is_infinity, \
183  .multiply = _name ## _multiply, \
184  .add = _name ## _add, \
185  }
186 
187 #endif /* _IPXE_WEIERSTRASS_H */
uint32_t base
Base.
Definition: librm.h:138
const uint8_t * base
Base point.
Definition: weierstrass.h:106
bigint_element_t * square
Cached Montgomery constant (R^2 mod N)
Definition: weierstrass.h:113
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
Definition: weierstrass.h:109
weierstrass_multiple
Indexes for stored multiples of the field prime.
Definition: weierstrass.h:71
bigint_element_t * mont[WEIERSTRASS_NUM_MONT]
Definition: weierstrass.h:124
Cryptographic API.
bigint_element_t * b3
Cached constant "3b", in Montgomery form.
Definition: weierstrass.h:122
Big integer support.
int weierstrass_multiply(struct weierstrass_curve *curve, const void *base, const void *scalar, void *result)
Multiply curve point by scalar.
Definition: weierstrass.c:952
#define WEIERSTRASS_NUM_CACHED
Number of cached big integers for each Weierstrass curve.
Definition: weierstrass.h:82
uint32_t bigint_element_t
Element of a big integer.
Definition: bigint.h:16
bigint_element_t * fermat
Cached constant "N-2" (for Fermat's little theorem)
Definition: weierstrass.h:111
const uint8_t * b_raw
Constant "b".
Definition: weierstrass.h:104
bigint_element_t * a
Cached constant "a", in Montgomery form.
Definition: weierstrass.h:120
#define WEIERSTRASS_NUM_MONT
Number of cached in Montgomery form for each Weierstrass curve.
Definition: weierstrass.h:79
const char * name
Curve name.
Definition: weierstrass.h:96
unsigned char uint8_t
Definition: stdint.h:10
size_t len
Length of raw scalar values.
Definition: weierstrass.h:98
bigint_element_t * one
Cached constant "1", in Montgomery form.
Definition: weierstrass.h:118
uint16_t result
Definition: hyperv.h:33
int weierstrass_add_once(struct weierstrass_curve *curve, const void *addend, const void *augend, void *result)
Add curve points (as a one-off operation)
Definition: weierstrass.c:999
FILE_SECBOOT(PERMITTED)
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:94
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
int weierstrass_is_infinity(struct weierstrass_curve *curve, const void *point)
Check if this is the point at infinity.
Definition: weierstrass.c:919
const uint8_t * prime_raw
Field prime.
Definition: weierstrass.h:100
const uint8_t * a_raw
Constant "a".
Definition: weierstrass.h:102
A Weierstrass elliptic curve.
Definition: weierstrass.h:92