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#include <ipxe/elliptic.h>
16
17/** Number of axes in Weierstrass curve point representation */
18#define WEIERSTRASS_AXES 2
19
20/**
21 * Maximum multiple of field prime encountered during calculations
22 *
23 * Calculations are performed using values modulo a small multiple of
24 * the field prime, rather than modulo the field prime itself. This
25 * allows explicit reductions after additions, subtractions, and
26 * relaxed Montgomery multiplications to be omitted entirely, provided
27 * that we keep careful track of the field prime multiple for each
28 * intermediate value.
29 *
30 * Relaxed Montgomery multiplication will produce a result in the
31 * range t < (1+(m^2)/k)N, where m is this maximum multiple of the
32 * field prime, and k is the constant in R > kN representing the
33 * leading zero padding in the big integer representation of the field
34 * prime. We choose to set k=m^2 so that multiplications will always
35 * produce a result in the range t < 2N.
36 *
37 * A lower value of k would be possible, at the cost of having to keep
38 * track of the field prime multiples used at each multiplication
39 * input (rather than keeping track only of a single global maximum).
40 * This would gain nothing in practice: any value of k below around
41 * 2^32 will end up requiring just a single extra big integer element.
42 *
43 * This is expressed as the base-two logarithm of the multiple
44 * (rounded up), to simplify compile-time calculations.
45 */
46#define WEIERSTRASS_MAX_MULT_LOG2 5 /* maximum reached is mod 20N */
47
48/**
49 * Determine number of elements in scalar values for a Weierstrass curve
50 *
51 * @v len Length of field prime, in bytes
52 * @ret size Number of elements
53 */
54#define weierstrass_size( len ) \
55 bigint_required_size ( (len) + \
56 ( ( 2 * WEIERSTRASS_MAX_MULT_LOG2 + 7 ) \
57 / 8 ) )
58
59/**
60 * Define a Weierstrass projective co-ordinate type
61 *
62 * @v size Number of elements in scalar values
63 * @ret type Projective co-ordinate type
64 */
65#define weierstrass_t( size ) \
66 union { \
67 bigint_t ( size ) axis[3]; \
68 struct { \
69 bigint_t ( size ) x; \
70 bigint_t ( size ) y; \
71 bigint_t ( size ) z; \
72 }; \
73 bigint_t ( size * 2 ) xy; \
74 bigint_t ( size * 3 ) all; \
75 }
76
77/** Indexes for stored multiples of the field prime */
84
85/** Number of cached in Montgomery form for each Weierstrass curve */
86#define WEIERSTRASS_NUM_MONT 3
87
88/** Number of cached big integers for each Weierstrass curve */
89#define WEIERSTRASS_NUM_CACHED \
90 ( WEIERSTRASS_NUM_MULTIPLES + \
91 1 /* fermat */ + 1 /* mont */ + \
92 WEIERSTRASS_NUM_MONT )
93
94/**
95 * A Weierstrass elliptic curve
96 *
97 * This is an elliptic curve y^2 = x^3 + ax + b
98 */
100 /** Number of elements in scalar values */
101 const unsigned int size;
102 /** Length of raw scalar values */
103 size_t len;
104 /** Field prime */
106 /** Constant "a" */
108 /** Constant "b" */
110 /** Base point */
111 const uint8_t *base;
112
113 /** Cached field prime "N" (and multiples thereof) */
115 /** Cached constant "N-2" (for Fermat's little theorem) */
117 /** Cached Montgomery constant (R^2 mod N) */
119 /** Cached constants in Montgomery form */
120 union {
121 struct {
122 /** Cached constant "1", in Montgomery form */
124 /** Cached constant "a", in Montgomery form */
126 /** Cached constant "3b", in Montgomery form */
128 };
130 };
131};
132
133extern int weierstrass_is_infinity ( struct elliptic_curve *curve,
134 const void *point );
135extern int weierstrass_multiply ( struct elliptic_curve *curve,
136 const void *base, const void *scalar,
137 void *result );
138extern int weierstrass_add_once ( struct elliptic_curve *curve,
139 const void *addend, const void *augend,
140 void *result );
141extern void weierstrass_share ( struct exchange_algorithm *exchange,
142 const void *private, void *public );
143extern int weierstrass_agree ( struct exchange_algorithm *exchange,
144 const void *private, const void *partner,
145 void *shared );
146
147/** Define a Weierstrass curve */
148#define WEIERSTRASS_CURVE( _name, _curve, _len, _prime, _a, _b, _base, \
149 _order ) \
150 static bigint_t ( weierstrass_size(_len) ) \
151 _name ## _cache[WEIERSTRASS_NUM_CACHED]; \
152 static struct weierstrass_curve _name ## _weierstrass = { \
153 .size = weierstrass_size(_len), \
154 .len = (_len), \
155 .prime_raw = (_prime), \
156 .a_raw = (_a), \
157 .b_raw = (_b), \
158 .base = (_base), \
159 .prime = { \
160 (_name ## _cache)[0].element, \
161 (_name ## _cache)[1].element, \
162 (_name ## _cache)[2].element, \
163 }, \
164 .fermat = (_name ## _cache)[3].element, \
165 .square = (_name ## _cache)[4].element, \
166 .one = (_name ## _cache)[5].element, \
167 .a = (_name ## _cache)[6].element, \
168 .b3 = (_name ## _cache)[7].element, \
169 }; \
170 struct elliptic_curve _curve = { \
171 .name = #_name, \
172 .pointsize = ( (_len) * WEIERSTRASS_AXES ), \
173 .keysize = (_len), \
174 .base = (_base), \
175 .order = (_order), \
176 .is_infinity = weierstrass_is_infinity, \
177 .multiply = weierstrass_multiply, \
178 .add = weierstrass_add_once, \
179 .priv = &_name ## _weierstrass, \
180 }
181
182#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:15
Elliptic curves.
struct eth_slow_lacp_entity_tlv partner
Partner information.
Definition eth_slow.h:5
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
Big integer support.
Cryptographic API.
uint32_t base
Base.
Definition librm.h:3
An elliptic curve.
Definition crypto.h:246
A key exchange algorithm.
Definition crypto.h:210
A Weierstrass elliptic curve.
Definition weierstrass.h:99
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.
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.
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 elliptic_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:86
void weierstrass_share(struct exchange_algorithm *exchange, const void *private, void *public)
#define WEIERSTRASS_NUM_CACHED
Number of cached big integers for each Weierstrass curve.
Definition weierstrass.h:89
int weierstrass_agree(struct exchange_algorithm *exchange, const void *private, const void *partner, void *shared)
weierstrass_multiple
Indexes for stored multiples of the field prime.
Definition weierstrass.h:78
@ WEIERSTRASS_N
Definition weierstrass.h:79
@ WEIERSTRASS_2N
Definition weierstrass.h:80
@ WEIERSTRASS_4N
Definition weierstrass.h:81
@ WEIERSTRASS_NUM_MULTIPLES
Definition weierstrass.h:82
int weierstrass_multiply(struct elliptic_curve *curve, const void *base, const void *scalar, void *result)
Multiply curve point by scalar.
int weierstrass_add_once(struct elliptic_curve *curve, const void *addend, const void *augend, void *result)
Add curve points (as a one-off operation).