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