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
10FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11FILE_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 */
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" */
103 /** Constant "b" */
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
128extern int weierstrass_is_infinity ( struct weierstrass_curve *curve,
129 const void *point );
130extern int weierstrass_multiply ( struct weierstrass_curve *curve,
131 const void *base, const void *scalar,
132 void *result );
133extern 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 */
uint16_t result
Definition hyperv.h:33
unsigned char uint8_t
Definition stdint.h:10
uint32_t bigint_element_t
Element of a big integer.
Definition bigint.h:16
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
Big integer support.
Cryptographic API.
uint32_t base
Base.
Definition librm.h:3
A Weierstrass elliptic curve.
Definition weierstrass.h:92
bigint_element_t * mont[WEIERSTRASS_NUM_MONT]
const uint8_t * base
Base point.
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
size_t len
Length of raw scalar values.
Definition weierstrass.h:98
const uint8_t * a_raw
Constant "a".
bigint_element_t * one
Cached constant "1", in Montgomery form.
bigint_element_t * square
Cached Montgomery constant (R^2 mod N)
bigint_element_t * b3
Cached constant "3b", in Montgomery form.
const unsigned int size
Number of elements in scalar values.
Definition weierstrass.h:94
const char * name
Curve name.
Definition weierstrass.h:96
const uint8_t * b_raw
Constant "b".
bigint_element_t * fermat
Cached constant "N-2" (for Fermat's little theorem)
bigint_element_t * a
Cached constant "a", in Montgomery form.
const uint8_t * prime_raw
Field prime.
int weierstrass_is_infinity(struct weierstrass_curve *curve, const void *point)
Check if this is the point at infinity.
#define WEIERSTRASS_NUM_MONT
Number of cached in Montgomery form for each Weierstrass curve.
Definition weierstrass.h:79
int weierstrass_multiply(struct weierstrass_curve *curve, const void *base, const void *scalar, void *result)
Multiply curve point by scalar.
#define WEIERSTRASS_NUM_CACHED
Number of cached big integers for each Weierstrass curve.
Definition weierstrass.h:82
int weierstrass_add_once(struct weierstrass_curve *curve, const void *addend, const void *augend, void *result)
Add curve points (as a one-off operation)
weierstrass_multiple
Indexes for stored multiples of the field prime.
Definition weierstrass.h:71
@ WEIERSTRASS_N
Definition weierstrass.h:72
@ WEIERSTRASS_2N
Definition weierstrass.h:73
@ WEIERSTRASS_4N
Definition weierstrass.h:74
@ WEIERSTRASS_NUM_MULTIPLES
Definition weierstrass.h:75