iPXE
bigint.h
Go to the documentation of this file.
1 #ifndef _IPXE_BIGINT_H
2 #define _IPXE_BIGINT_H
3 
4 /** @file
5  *
6  * Big integer support
7  */
8 
9 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
10 FILE_SECBOOT ( PERMITTED );
11 
12 #include <assert.h>
13 
14 /**
15  * Define a big-integer type
16  *
17  * @v size Number of elements
18  * @ret bigint_t Big integer type
19  */
20 #define bigint_t( size ) \
21  struct { \
22  bigint_element_t element[ (size) ]; \
23  }
24 
25 /**
26  * Determine number of elements required for a big-integer type
27  *
28  * @v len Maximum length of big integer, in bytes
29  * @ret size Number of elements
30  */
31 #define bigint_required_size( len ) \
32  ( (len) ? ( ( (len) + sizeof ( bigint_element_t ) - 1 ) / \
33  sizeof ( bigint_element_t ) ) : 1 )
34 
35 /**
36  * Determine number of elements in big-integer type
37  *
38  * @v bigint Big integer
39  * @ret size Number of elements
40  */
41 #define bigint_size( bigint ) \
42  ( sizeof ( *(bigint) ) / sizeof ( (bigint)->element[0] ) )
43 
44 /**
45  * Transcribe big integer (for debugging)
46  *
47  * @v value Big integer to be transcribed
48  * @ret string Big integer in string form (may be abbreviated)
49  */
50 #define bigint_ntoa( value ) ( { \
51  unsigned int size = bigint_size (value); \
52  bigint_ntoa_raw ( (value)->element, size ); \
53  } )
54 
55 /**
56  * Initialise big integer
57  *
58  * @v value Big integer to initialise
59  * @v data Raw data
60  * @v len Length of raw data
61  */
62 #define bigint_init( value, data, len ) do { \
63  unsigned int size = bigint_size (value); \
64  assert ( (len) <= ( size * sizeof ( (value)->element[0] ) ) ); \
65  bigint_init_raw ( (value)->element, size, (data), (len) ); \
66  } while ( 0 )
67 
68 /**
69  * Finalise big integer
70  *
71  * @v value Big integer to finalise
72  * @v out Output buffer
73  * @v len Length of output buffer
74  */
75 #define bigint_done( value, out, len ) do { \
76  unsigned int size = bigint_size (value); \
77  bigint_done_raw ( (value)->element, size, (out), (len) ); \
78  } while ( 0 )
79 
80 /**
81  * Add big integers
82  *
83  * @v addend Big integer to add
84  * @v value Big integer to be added to
85  * @ret carry Carry out
86  */
87 #define bigint_add( addend, value ) ( { \
88  unsigned int size = bigint_size (addend); \
89  bigint_add_raw ( (addend)->element, (value)->element, size ); \
90  } )
91 
92 /**
93  * Subtract big integers
94  *
95  * @v subtrahend Big integer to subtract
96  * @v value Big integer to be subtracted from
97  * @ret borrow Borrow out
98  */
99 #define bigint_subtract( subtrahend, value ) ( { \
100  unsigned int size = bigint_size (subtrahend); \
101  bigint_subtract_raw ( (subtrahend)->element, (value)->element, \
102  size ); \
103  } )
104 
105 /**
106  * Shift big integer left
107  *
108  * @v value Big integer
109  * @ret out Bit shifted out
110  */
111 #define bigint_shl( value ) ( { \
112  unsigned int size = bigint_size (value); \
113  bigint_shl_raw ( (value)->element, size ); \
114  } )
115 
116 /**
117  * Shift big integer right
118  *
119  * @v value Big integer
120  * @ret out Bit shifted out
121  */
122 #define bigint_shr( value ) ( { \
123  unsigned int size = bigint_size (value); \
124  bigint_shr_raw ( (value)->element, size ); \
125  } )
126 
127 /**
128  * Test if big integer is equal to zero
129  *
130  * @v value Big integer
131  * @v size Number of elements
132  * @ret is_zero Big integer is equal to zero
133  */
134 #define bigint_is_zero( value ) ( { \
135  unsigned int size = bigint_size (value); \
136  bigint_is_zero_raw ( (value)->element, size ); } )
137 
138 /**
139  * Compare big integers
140  *
141  * @v value Big integer
142  * @v reference Reference big integer
143  * @ret geq Big integer is greater than or equal to the reference
144  */
145 #define bigint_is_geq( value, reference ) ( { \
146  unsigned int size = bigint_size (value); \
147  bigint_is_geq_raw ( (value)->element, (reference)->element, \
148  size ); } )
149 
150 /**
151  * Set bit in big integer
152  *
153  * @v value Big integer
154  * @v bit Bit to set
155  */
156 #define bigint_set_bit( value, bit ) do { \
157  unsigned int size = bigint_size (value); \
158  bigint_set_bit_raw ( (value)->element, size, bit ); \
159  } while ( 0 )
160 
161 /**
162  * Clear bit in big integer
163  *
164  * @v value Big integer
165  * @v bit Bit to set
166  */
167 #define bigint_clear_bit( value, bit ) do { \
168  unsigned int size = bigint_size (value); \
169  bigint_clear_bit_raw ( (value)->element, size, bit ); \
170  } while ( 0 )
171 
172 /**
173  * Test if bit is set in big integer
174  *
175  * @v value Big integer
176  * @v bit Bit to test
177  * @ret is_set Bit is set
178  */
179 #define bigint_bit_is_set( value, bit ) ( { \
180  unsigned int size = bigint_size (value); \
181  bigint_bit_is_set_raw ( (value)->element, size, bit ); } )
182 
183 /**
184  * Test if most significant bit is set in big integer
185  *
186  * @v value Big integer
187  * @ret is_set Most significant bit is set
188  */
189 #define bigint_msb_is_set( value ) ( { \
190  unsigned int size = bigint_size (value); \
191  bigint_msb_is_set_raw ( (value)->element, size ); } )
192 
193 /**
194  * Find highest bit set in big integer
195  *
196  * @v value Big integer
197  * @ret max_bit Highest bit set + 1 (or 0 if no bits set)
198  */
199 #define bigint_max_set_bit( value ) ( { \
200  unsigned int size = bigint_size (value); \
201  bigint_max_set_bit_raw ( (value)->element, size ); } )
202 
203 /**
204  * Grow big integer
205  *
206  * @v source Source big integer
207  * @v dest Destination big integer
208  */
209 #define bigint_grow( source, dest ) do { \
210  unsigned int source_size = bigint_size (source); \
211  unsigned int dest_size = bigint_size (dest); \
212  bigint_grow_raw ( (source)->element, source_size, \
213  (dest)->element, dest_size ); \
214  } while ( 0 )
215 
216 /**
217  * Shrink big integer
218  *
219  * @v source Source big integer
220  * @v dest Destination big integer
221  */
222 #define bigint_shrink( source, dest ) do { \
223  unsigned int source_size = bigint_size (source); \
224  unsigned int dest_size = bigint_size (dest); \
225  bigint_shrink_raw ( (source)->element, source_size, \
226  (dest)->element, dest_size ); \
227  } while ( 0 )
228 
229 /**
230  * Copy big integer
231  *
232  * @v source Source big integer
233  * @v dest Destination big integer
234  */
235 #define bigint_copy( source, dest ) do { \
236  build_assert ( sizeof ( *(source) ) == sizeof ( *(dest) ) ); \
237  bigint_shrink ( (source), (dest) ); \
238  } while ( 0 )
239 
240 /**
241  * Conditionally swap big integers (in constant time)
242  *
243  * @v first Big integer to be conditionally swapped
244  * @v second Big integer to be conditionally swapped
245  * @v swap Swap first and second big integers
246  */
247 #define bigint_swap( first, second, swap ) do { \
248  unsigned int size = bigint_size (first); \
249  bigint_swap_raw ( (first)->element, (second)->element, size, \
250  (swap) ); \
251  } while ( 0 )
252 
253 /**
254  * Multiply big integers
255  *
256  * @v multiplicand Big integer to be multiplied
257  * @v multiplier Big integer to be multiplied
258  * @v result Big integer to hold result
259  */
260 #define bigint_multiply( multiplicand, multiplier, result ) do { \
261  unsigned int multiplicand_size = bigint_size (multiplicand); \
262  unsigned int multiplier_size = bigint_size (multiplier); \
263  bigint_multiply_raw ( (multiplicand)->element, \
264  multiplicand_size, (multiplier)->element, \
265  multiplier_size, (result)->element ); \
266  } while ( 0 )
267 
268 /**
269  * Reduce big integer R^2 modulo N
270  *
271  * @v modulus Big integer modulus
272  * @v result Big integer to hold result
273  */
274 #define bigint_reduce( modulus, result ) do { \
275  unsigned int size = bigint_size (modulus); \
276  bigint_reduce_raw ( (modulus)->element, (result)->element, \
277  size ); \
278  } while ( 0 )
279 
280 /**
281  * Compute inverse of odd big integer modulo any power of two
282  *
283  * @v invertend Odd big integer to be inverted
284  * @v inverse Big integer to hold result
285  */
286 #define bigint_mod_invert( invertend, inverse ) do { \
287  unsigned int size = bigint_size ( inverse ); \
288  bigint_mod_invert_raw ( (invertend)->element, \
289  (inverse)->element, size ); \
290  } while ( 0 )
291 
292 /**
293  * Perform relaxed Montgomery reduction (REDC) of a big integer
294  *
295  * @v modulus Big integer odd modulus
296  * @v value Big integer to be reduced
297  * @v result Big integer to hold result
298  * @ret carry Carry out
299  */
300 #define bigint_montgomery_relaxed( modulus, value, result ) ( { \
301  unsigned int size = bigint_size (modulus); \
302  bigint_montgomery_relaxed_raw ( (modulus)->element, \
303  (value)->element, \
304  (result)->element, size ); \
305  } )
306 
307 /**
308  * Perform classic Montgomery reduction (REDC) of a big integer
309  *
310  * @v modulus Big integer odd modulus
311  * @v value Big integer to be reduced
312  * @v result Big integer to hold result
313  */
314 #define bigint_montgomery( modulus, value, result ) do { \
315  unsigned int size = bigint_size (modulus); \
316  bigint_montgomery_raw ( (modulus)->element, (value)->element, \
317  (result)->element, size ); \
318  } while ( 0 )
319 
320 /**
321  * Perform generalised exponentiation via a Montgomery ladder
322  *
323  * @v result Big integer result (initialised to identity element)
324  * @v multiple Big integer multiple (initialised to generator)
325  * @v exponent Big integer exponent
326  * @v op Montgomery ladder commutative operation
327  * @v ctx Operation context (if needed)
328  * @v tmp Temporary working space (if needed)
329  */
330 #define bigint_ladder( result, multiple, exponent, op, ctx, tmp ) do { \
331  unsigned int size = bigint_size (result); \
332  unsigned int exponent_size = bigint_size (exponent); \
333  bigint_ladder_raw ( (result)->element, (multiple)->element, \
334  size, (exponent)->element, exponent_size, \
335  (op), (ctx), (tmp) ); \
336  } while ( 0 )
337 
338 /**
339  * Perform modular exponentiation of big integers
340  *
341  * @v base Big integer base
342  * @v modulus Big integer modulus
343  * @v exponent Big integer exponent
344  * @v result Big integer to hold result
345  * @v tmp Temporary working space
346  */
347 #define bigint_mod_exp( base, modulus, exponent, result, tmp ) do { \
348  unsigned int size = bigint_size (base); \
349  unsigned int exponent_size = bigint_size (exponent); \
350  bigint_mod_exp_raw ( (base)->element, (modulus)->element, \
351  (exponent)->element, (result)->element, \
352  size, exponent_size, tmp ); \
353  } while ( 0 )
354 
355 /**
356  * Calculate temporary working space required for moduluar exponentiation
357  *
358  * @v modulus Big integer modulus
359  * @ret len Length of temporary working space
360  */
361 #define bigint_mod_exp_tmp_len( modulus ) ( { \
362  unsigned int size = bigint_size (modulus); \
363  sizeof ( struct { \
364  bigint_t ( size ) temp[4]; \
365  } ); } )
366 
367 #include <bits/bigint.h>
368 
369 /**
370  * A big integer Montgomery ladder commutative operation
371  *
372  * @v operand Element 0 of first input operand (may overlap result)
373  * @v result Element 0 of second input operand and result
374  * @v size Number of elements in operands and result
375  * @v ctx Operation context (if needed)
376  * @v tmp Temporary working space (if needed)
377  */
378 typedef void ( bigint_ladder_op_t ) ( const bigint_element_t *operand0,
379  bigint_element_t *result0,
380  unsigned int size, const void *ctx,
381  void *tmp );
382 
383 /**
384  * Set bit in big integer
385  *
386  * @v value0 Element 0 of big integer
387  * @v size Number of elements
388  * @v bit Bit to set
389  */
390 static inline __attribute__ (( always_inline )) void
391 bigint_set_bit_raw ( bigint_element_t *value0, unsigned int size,
392  unsigned int bit ) {
393  bigint_t ( size ) __attribute__ (( may_alias )) *value =
394  ( ( void * ) value0 );
395  unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) );
396  unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) );
397 
398  value->element[index] |= ( 1UL << subindex );
399 }
400 
401 /**
402  * Clear bit in big integer
403  *
404  * @v value0 Element 0 of big integer
405  * @v size Number of elements
406  * @v bit Bit to clear
407  */
408 static inline __attribute__ (( always_inline )) void
409 bigint_clear_bit_raw ( bigint_element_t *value0, unsigned int size,
410  unsigned int bit ) {
411  bigint_t ( size ) __attribute__ (( may_alias )) *value =
412  ( ( void * ) value0 );
413  unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) );
414  unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) );
415 
416  value->element[index] &= ~( 1UL << subindex );
417 }
418 
419 /**
420  * Test if bit is set in big integer
421  *
422  * @v value0 Element 0 of big integer
423  * @v size Number of elements
424  * @v bit Bit to test
425  * @ret is_set Bit is set
426  */
427 static inline __attribute__ (( always_inline )) int
428 bigint_bit_is_set_raw ( const bigint_element_t *value0, unsigned int size,
429  unsigned int bit ) {
430  const bigint_t ( size ) __attribute__ (( may_alias )) *value =
431  ( ( const void * ) value0 );
432  unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) );
433  unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) );
434 
435  return ( !! ( value->element[index] & ( 1UL << subindex ) ) );
436 }
437 
438 /**
439  * Test if most significant bit is set in big integer
440  *
441  * @v value0 Element 0 of big integer
442  * @v size Number of elements
443  * @ret is_set Most significant bit is set
444  */
445 static inline __attribute__ (( always_inline )) int
446 bigint_msb_is_set_raw ( const bigint_element_t *value0, unsigned int size ) {
447  const bigint_t ( size ) __attribute__ (( may_alias )) *value =
448  ( ( const void * ) value0 );
449  unsigned int index = ( size - 1 );
450  unsigned int subindex = ( ( 8 * sizeof ( value->element[0] ) ) - 1 );
451 
452  return ( !! ( value->element[index] & ( 1UL << subindex ) ) );
453 }
454 
455 const char * bigint_ntoa_raw ( const bigint_element_t *value0,
456  unsigned int size );
457 void bigint_init_raw ( bigint_element_t *value0, unsigned int size,
458  const void *data, size_t len );
459 void bigint_done_raw ( const bigint_element_t *value0, unsigned int size,
460  void *out, size_t len );
461 int bigint_add_raw ( const bigint_element_t *addend0,
462  bigint_element_t *value0, unsigned int size );
463 int bigint_subtract_raw ( const bigint_element_t *subtrahend0,
464  bigint_element_t *value0, unsigned int size );
465 int bigint_shl_raw ( bigint_element_t *value0, unsigned int size );
466 int bigint_shr_raw ( bigint_element_t *value0, unsigned int size );
467 int bigint_is_zero_raw ( const bigint_element_t *value0, unsigned int size );
470  unsigned int size );
471 int bigint_bit_is_set_raw ( const bigint_element_t *value0, unsigned int size,
472  unsigned int bit );
474  unsigned int size );
475 void bigint_grow_raw ( const bigint_element_t *source0,
476  unsigned int source_size, bigint_element_t *dest0,
477  unsigned int dest_size );
478 void bigint_shrink_raw ( const bigint_element_t *source0,
479  unsigned int source_size, bigint_element_t *dest0,
480  unsigned int dest_size );
481 void bigint_swap_raw ( bigint_element_t *first0, bigint_element_t *second0,
482  unsigned int size, int swap );
483 void bigint_multiply_one ( const bigint_element_t multiplicand,
487 void bigint_multiply_raw ( const bigint_element_t *multiplicand0,
488  unsigned int multiplicand_size,
489  const bigint_element_t *multiplier0,
490  unsigned int multiplier_size,
491  bigint_element_t *result0 );
492 void bigint_reduce_raw ( const bigint_element_t *modulus0,
493  bigint_element_t *result0, unsigned int size );
494 void bigint_mod_invert_raw ( const bigint_element_t *invertend0,
495  bigint_element_t *inverse0, unsigned int size );
496 int bigint_montgomery_relaxed_raw ( const bigint_element_t *modulus0,
498  bigint_element_t *result0,
499  unsigned int size );
500 void bigint_montgomery_raw ( const bigint_element_t *modulus0,
502  bigint_element_t *result0, unsigned int size );
503 void bigint_ladder_raw ( bigint_element_t *result0,
504  bigint_element_t *multiple0, unsigned int size,
505  const bigint_element_t *exponent0,
506  unsigned int exponent_size, bigint_ladder_op_t *op,
507  const void *ctx, void *tmp );
508 void bigint_mod_exp_ladder ( const bigint_element_t *multiplier0,
509  bigint_element_t *result0, unsigned int size,
510  const void *ctx, void *tmp );
511 void bigint_mod_exp_raw ( const bigint_element_t *base0,
512  const bigint_element_t *modulus0,
513  const bigint_element_t *exponent0,
514  bigint_element_t *result0,
515  unsigned int size, unsigned int exponent_size,
516  void *tmp );
517 
518 #endif /* _IPXE_BIGINT_H */
void bigint_grow_raw(const bigint_element_t *source0, unsigned int source_size, bigint_element_t *dest0, unsigned int dest_size)
static const uint32_t * reference0
Definition: bigint.h:198
int carry
Definition: bigint.h:68
FILE_SECBOOT(PERMITTED)
const char * bigint_ntoa_raw(const bigint_element_t *value0, unsigned int size)
Transcribe big integer (for debugging)
Definition: bigint.c:48
unsigned int subindex
Definition: bigint.h:396
static __attribute__((always_inline)) void bigint_set_bit_raw(bigint_element_t *value0
Set bit in big integer.
int bigint_max_set_bit_raw(const bigint_element_t *value0, unsigned int size)
long index
Definition: bigint.h:65
static unsigned int unsigned int bit
Definition: bigint.h:392
void bigint_multiply_one(const bigint_element_t multiplicand, const bigint_element_t multiplier, bigint_element_t *result, bigint_element_t *carry)
void bigint_swap_raw(bigint_element_t *first0, bigint_element_t *second0, unsigned int size, int swap)
Conditionally swap big integers (in constant time)
Definition: bigint.c:92
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static uint32_t * value0
Definition: bigint.h:61
void bigint_multiply_raw(const bigint_element_t *multiplicand0, unsigned int multiplicand_size, const bigint_element_t *multiplier0, unsigned int multiplier_size, bigint_element_t *result0)
Multiply big integers.
Definition: bigint.c:118
unsigned long tmp
Definition: linux_pci.h:65
static unsigned int const void size_t len
Definition: bigint.h:28
Assertions.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static unsigned int const void * data
Definition: bigint.h:27
void bigint_mod_invert_raw(const bigint_element_t *invertend0, bigint_element_t *inverse0, unsigned int size)
Compute inverse of odd big integer modulo any power of two.
Definition: bigint.c:318
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int result
Definition: bigint.h:178
uint32_t bigint_element_t
Element of a big integer.
Definition: bigint.h:16
void bigint_init_raw(bigint_element_t *value0, unsigned int size, const void *data, size_t len)
static unsigned int uint32_t unsigned int dest_size
Definition: bigint.h:252
#define bigint_t(size)
Define a big-integer type.
Definition: bigint.h:20
void bigint_mod_exp_raw(const bigint_element_t *base0, const bigint_element_t *modulus0, const bigint_element_t *exponent0, bigint_element_t *result0, unsigned int size, unsigned int exponent_size, void *tmp)
Perform modular exponentiation of big integers.
Definition: bigint.c:752
int bigint_montgomery_relaxed_raw(const bigint_element_t *modulus0, bigint_element_t *value0, bigint_element_t *result0, unsigned int size)
Perform relaxed Montgomery reduction (REDC) of a big integer.
Definition: bigint.c:488
void bigint_ladder_raw(bigint_element_t *result0, bigint_element_t *multiple0, unsigned int size, const bigint_element_t *exponent0, unsigned int exponent_size, bigint_ladder_op_t *op, const void *ctx, void *tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition: bigint.c:632
int bigint_bit_is_set_raw(const bigint_element_t *value0, unsigned int size, unsigned int bit)
void bigint_mod_exp_ladder(const bigint_element_t *multiplier0, bigint_element_t *result0, unsigned int size, const void *ctx, void *tmp)
Perform modular multiplication as part of a Montgomery ladder.
Definition: bigint.c:720
void bigint_reduce_raw(const bigint_element_t *modulus0, bigint_element_t *result0, unsigned int size)
Reduce big integer R^2 modulo N.
Definition: bigint.c:189
int bigint_shl_raw(bigint_element_t *value0, unsigned int size)
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
static const uint32_t multiplier
Port multiplier number.
Definition: bigint.h:335
static unsigned int source_size
Definition: bigint.h:251
void bigint_shrink_raw(const bigint_element_t *source0, unsigned int source_size, bigint_element_t *dest0, unsigned int dest_size)
void bigint_done_raw(const bigint_element_t *value0, unsigned int size, void *out, size_t len)
int out
Definition: bigint.h:130
int bigint_add_raw(const bigint_element_t *addend0, bigint_element_t *value0, unsigned int size)
void() bigint_ladder_op_t(const bigint_element_t *operand0, bigint_element_t *result0, unsigned int size, const void *ctx, void *tmp)
A big integer Montgomery ladder commutative operation.
Definition: bigint.h:378
int bigint_shr_raw(bigint_element_t *value0, unsigned int size)
int bigint_subtract_raw(const bigint_element_t *subtrahend0, bigint_element_t *value0, unsigned int size)
int bigint_is_zero_raw(const bigint_element_t *value0, unsigned int size)
static unsigned int uint32_t * dest0
Definition: bigint.h:251
void bigint_montgomery_raw(const bigint_element_t *modulus0, bigint_element_t *value0, bigint_element_t *result0, unsigned int size)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.c:565
static unsigned int size
Definition: bigint.h:27
Big integer support.
int bigint_is_geq_raw(const bigint_element_t *value0, const bigint_element_t *reference0, unsigned int size)