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