iPXE
bigint.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 #include <stdint.h>
28 #include <string.h>
29 #include <assert.h>
30 #include <stdio.h>
31 #include <ipxe/bigint.h>
32 
33 /** @file
34  *
35  * Big integer support
36  */
37 
38 /** Minimum number of least significant bytes included in transcription */
39 #define BIGINT_NTOA_LSB_MIN 16
40 
41 /**
42  * Transcribe big integer (for debugging)
43  *
44  * @v value0 Element 0 of big integer to be transcribed
45  * @v size Number of elements
46  * @ret string Big integer in string form (may be abbreviated)
47  */
48 const char * bigint_ntoa_raw ( const bigint_element_t *value0,
49  unsigned int size ) {
50  const bigint_t ( size ) __attribute__ (( may_alias ))
51  *value = ( ( const void * ) value0 );
53  static char buf[256];
54  unsigned int count;
55  int threshold;
56  uint8_t byte;
57  char *tmp;
58  int i;
59 
60  /* Calculate abbreviation threshold, if any */
61  count = ( size * sizeof ( element ) );
62  threshold = count;
63  if ( count >= ( ( sizeof ( buf ) - 1 /* NUL */ ) / 2 /* "xx" */ ) ) {
64  threshold -= ( ( sizeof ( buf ) - 3 /* "..." */
65  - ( BIGINT_NTOA_LSB_MIN * 2 /* "xx" */ )
66  - 1 /* NUL */ ) / 2 /* "xx" */ );
67  }
68 
69  /* Transcribe bytes, abbreviating with "..." if necessary */
70  for ( tmp = buf, i = ( count - 1 ) ; i >= 0 ; i-- ) {
71  element = value->element[ i / sizeof ( element ) ];
72  byte = ( element >> ( 8 * ( i % sizeof ( element ) ) ) );
73  tmp += sprintf ( tmp, "%02x", byte );
74  if ( i == threshold ) {
75  tmp += sprintf ( tmp, "..." );
77  }
78  }
79  assert ( tmp < ( buf + sizeof ( buf ) ) );
80 
81  return buf;
82 }
83 
84 /**
85  * Conditionally swap big integers (in constant time)
86  *
87  * @v first0 Element 0 of big integer to be conditionally swapped
88  * @v second0 Element 0 of big integer to be conditionally swapped
89  * @v size Number of elements in big integers
90  * @v swap Swap first and second big integers
91  */
93  unsigned int size, int swap ) {
94  bigint_element_t mask;
96  unsigned int i;
97 
98  /* Construct mask */
99  mask = ( ( bigint_element_t ) ( ! swap ) - 1 );
100 
101  /* Conditionally swap elements */
102  for ( i = 0 ; i < size ; i++ ) {
103  xor = ( mask & ( first0[i] ^ second0[i] ) );
104  first0[i] ^= xor;
105  second0[i] ^= xor;
106  }
107 }
108 
109 /**
110  * Multiply big integers
111  *
112  * @v multiplicand0 Element 0 of big integer to be multiplied
113  * @v multiplicand_size Number of elements in multiplicand
114  * @v multiplier0 Element 0 of big integer to be multiplied
115  * @v multiplier_size Number of elements in multiplier
116  * @v result0 Element 0 of big integer to hold result
117  */
118 void bigint_multiply_raw ( const bigint_element_t *multiplicand0,
119  unsigned int multiplicand_size,
120  const bigint_element_t *multiplier0,
121  unsigned int multiplier_size,
122  bigint_element_t *result0 ) {
123  unsigned int result_size = ( multiplicand_size + multiplier_size );
124  const bigint_t ( multiplicand_size ) __attribute__ (( may_alias ))
125  *multiplicand = ( ( const void * ) multiplicand0 );
126  const bigint_t ( multiplier_size ) __attribute__ (( may_alias ))
127  *multiplier = ( ( const void * ) multiplier0 );
128  bigint_t ( result_size ) __attribute__ (( may_alias ))
129  *result = ( ( void * ) result0 );
130  bigint_element_t multiplicand_element;
131  const bigint_element_t *multiplier_element;
132  bigint_element_t *result_element;
133  bigint_element_t carry_element;
134  unsigned int i;
135  unsigned int j;
136 
137  /* Zero required portion of result
138  *
139  * All elements beyond the length of the multiplier will be
140  * written before they are read, and so do not need to be
141  * zeroed in advance.
142  */
143  memset ( result, 0, sizeof ( *multiplier ) );
144 
145  /* Multiply integers one element at a time, adding the low
146  * half of the double-element product directly into the
147  * result, and maintaining a running single-element carry.
148  *
149  * The running carry can never overflow beyond a single
150  * element. At each step, the calculation we perform is:
151  *
152  * carry:result[i+j] := ( ( multiplicand[i] * multiplier[j] )
153  * + result[i+j] + carry )
154  *
155  * The maximum value (for n-bit elements) is therefore:
156  *
157  * (2^n - 1)*(2^n - 1) + (2^n - 1) + (2^n - 1) = 2^(2n) - 1
158  *
159  * This is precisely the maximum value for a 2n-bit integer,
160  * and so the carry out remains within the range of an n-bit
161  * integer, i.e. a single element.
162  */
163  for ( i = 0 ; i < multiplicand_size ; i++ ) {
164  multiplicand_element = multiplicand->element[i];
165  multiplier_element = &multiplier->element[0];
166  result_element = &result->element[i];
167  carry_element = 0;
168  for ( j = 0 ; j < multiplier_size ; j++ ) {
169  bigint_multiply_one ( multiplicand_element,
170  *(multiplier_element++),
171  result_element++,
172  &carry_element );
173  }
174  *result_element = carry_element;
175  }
176 }
177 
178 /**
179  * Reduce big integer R^2 modulo N
180  *
181  * @v modulus0 Element 0 of big integer modulus
182  * @v result0 Element 0 of big integer to hold result
183  * @v size Number of elements in modulus and result
184  *
185  * Reduce the value R^2 modulo N, where R=2^n and n is the number of
186  * bits in the representation of the modulus N, including any leading
187  * zero bits.
188  */
189 void bigint_reduce_raw ( const bigint_element_t *modulus0,
190  bigint_element_t *result0, unsigned int size ) {
191  const bigint_t ( size ) __attribute__ (( may_alias ))
192  *modulus = ( ( const void * ) modulus0 );
193  bigint_t ( size ) __attribute__ (( may_alias ))
194  *result = ( ( void * ) result0 );
195  const unsigned int width = ( 8 * sizeof ( bigint_element_t ) );
196  unsigned int shift;
197  int max;
198  int sign;
199  int msb;
200  int carry;
201 
202  /* We have the constants:
203  *
204  * N = modulus
205  *
206  * n = number of bits in the modulus (including any leading zeros)
207  *
208  * R = 2^n
209  *
210  * Let r be the extension of the n-bit result register by a
211  * separate two's complement sign bit, such that -R <= r < R,
212  * and define:
213  *
214  * x = r * 2^k
215  *
216  * as the value being reduced modulo N, where k is a
217  * non-negative integer bit shift.
218  *
219  * We want to reduce the initial value R^2=2^(2n), which we
220  * may trivially represent using r=1 and k=2n.
221  *
222  * We then iterate over decrementing k, maintaining the loop
223  * invariant:
224  *
225  * -N <= r < N
226  *
227  * On each iteration we must first double r, to compensate for
228  * having decremented k:
229  *
230  * k' = k - 1
231  *
232  * r' = 2r
233  *
234  * x = r * 2^k = 2r * 2^(k-1) = r' * 2^k'
235  *
236  * Note that doubling the n-bit result register will create a
237  * value of n+1 bits: this extra bit needs to be handled
238  * separately during the calculation.
239  *
240  * We then subtract N (if r is currently non-negative) or add
241  * N (if r is currently negative) to restore the loop
242  * invariant:
243  *
244  * 0 <= r < N => r" = 2r - N => -N <= r" < N
245  * -N <= r < 0 => r" = 2r + N => -N <= r" < N
246  *
247  * Note that since N may use all n bits, the most significant
248  * bit of the n-bit result register is not a valid two's
249  * complement sign bit for r: the extra sign bit therefore
250  * also needs to be handled separately.
251  *
252  * Once we reach k=0, we have x=r and therefore:
253  *
254  * -N <= x < N
255  *
256  * After this last loop iteration (with k=0), we may need to
257  * add a single multiple of N to ensure that x is positive,
258  * i.e. lies within the range 0 <= x < N.
259  *
260  * Since neither the modulus nor the value R^2 are secret, we
261  * may elide approximately half of the total number of
262  * iterations by constructing the initial representation of
263  * R^2 as r=2^m and k=2n-m (for some m such that 2^m < N).
264  */
265 
266  /* Initialise x=R^2 */
267  memset ( result, 0, sizeof ( *result ) );
268  max = ( bigint_max_set_bit ( modulus ) - 2 );
269  if ( max < 0 ) {
270  /* Degenerate case of N=0 or N=1: return a zero result */
271  return;
272  }
274  shift = ( ( 2 * size * width ) - max );
275  sign = 0;
276 
277  /* Iterate as described above */
278  while ( shift-- ) {
279 
280  /* Calculate 2r, storing extra bit separately */
281  msb = bigint_shl ( result );
282 
283  /* Add or subtract N according to current sign */
284  if ( sign ) {
285  carry = bigint_add ( modulus, result );
286  } else {
287  carry = bigint_subtract ( modulus, result );
288  }
289 
290  /* Calculate new sign of result
291  *
292  * We know the result lies in the range -N <= r < N
293  * and so the tuple (old sign, msb, carry) cannot ever
294  * take the values (0, 1, 0) or (1, 0, 0). We can
295  * therefore treat these as don't-care inputs, which
296  * allows us to simplify the boolean expression by
297  * ignoring the old sign completely.
298  */
299  assert ( ( sign == msb ) || carry );
300  sign = ( msb ^ carry );
301  }
302 
303  /* Add N to make result positive if necessary */
304  if ( sign )
305  bigint_add ( modulus, result );
306 
307  /* Sanity check */
308  assert ( ! bigint_is_geq ( result, modulus ) );
309 }
310 
311 /**
312  * Compute inverse of odd big integer modulo any power of two
313  *
314  * @v invertend0 Element 0 of odd big integer to be inverted
315  * @v inverse0 Element 0 of big integer to hold result
316  * @v size Number of elements in invertend and result
317  */
318 void bigint_mod_invert_raw ( const bigint_element_t *invertend0,
319  bigint_element_t *inverse0, unsigned int size ) {
320  const bigint_t ( size ) __attribute__ (( may_alias ))
321  *invertend = ( ( const void * ) invertend0 );
322  bigint_t ( size ) __attribute__ (( may_alias ))
323  *inverse = ( ( void * ) inverse0 );
324  bigint_element_t accum;
326  unsigned int i;
327 
328  /* Sanity check */
329  assert ( bigint_bit_is_set ( invertend, 0 ) );
330 
331  /* Initialise output */
332  memset ( inverse, 0xff, sizeof ( *inverse ) );
333 
334  /* Compute inverse modulo 2^(width)
335  *
336  * This method is a lightly modified version of the pseudocode
337  * presented in "A New Algorithm for Inversion mod p^k (Koç,
338  * 2017)".
339  *
340  * Each inner loop iteration calculates one bit of the
341  * inverse. The residue value is the two's complement
342  * negation of the value "b" as used by Koç, to allow for
343  * division by two using a logical right shift (since we have
344  * no arithmetic right shift operation for big integers).
345  *
346  * The residue is stored in the as-yet uncalculated portion of
347  * the inverse. The size of the residue therefore decreases
348  * by one element for each outer loop iteration. Trivial
349  * inspection of the algorithm shows that any higher bits
350  * could not contribute to the eventual output value, and so
351  * we may safely reuse storage this way.
352  *
353  * Due to the suffix property of inverses mod 2^k, the result
354  * represents the least significant bits of the inverse modulo
355  * an arbitrarily large 2^k.
356  */
357  for ( i = size ; i > 0 ; i-- ) {
358  const bigint_t ( i ) __attribute__ (( may_alias ))
359  *addend = ( ( const void * ) invertend );
360  bigint_t ( i ) __attribute__ (( may_alias ))
361  *residue = ( ( void * ) inverse );
362 
363  /* Calculate one element's worth of inverse bits */
364  for ( accum = 0, bit = 1 ; bit ; bit <<= 1 ) {
365  if ( bigint_bit_is_set ( residue, 0 ) ) {
366  accum |= bit;
367  bigint_add ( addend, residue );
368  }
369  bigint_shr ( residue );
370  }
371 
372  /* Store in the element no longer required to hold residue */
373  inverse->element[ i - 1 ] = accum;
374  }
375 
376  /* Correct order of inverse elements */
377  for ( i = 0 ; i < ( size / 2 ) ; i++ ) {
378  accum = inverse->element[i];
379  inverse->element[i] = inverse->element[ size - 1 - i ];
380  inverse->element[ size - 1 - i ] = accum;
381  }
382 }
383 
384 /**
385  * Perform relaxed Montgomery reduction (REDC) of a big integer
386  *
387  * @v modulus0 Element 0 of big integer odd modulus
388  * @v value0 Element 0 of big integer to be reduced
389  * @v result0 Element 0 of big integer to hold result
390  * @v size Number of elements in modulus and result
391  * @ret carry Carry out
392  *
393  * The value to be reduced will be made divisible by the size of the
394  * modulus while retaining its residue class (i.e. multiples of the
395  * modulus will be added until the low half of the value is zero).
396  *
397  * The result may be expressed as
398  *
399  * tR = x + mN
400  *
401  * where x is the input value, N is the modulus, R=2^n (where n is the
402  * number of bits in the representation of the modulus, including any
403  * leading zero bits), and m is the number of multiples of the modulus
404  * added to make the result tR divisible by R.
405  *
406  * The maximum addend is mN <= (R-1)*N (and such an m can be proven to
407  * exist since N is limited to being odd and therefore coprime to R).
408  *
409  * Since the result of this addition is one bit larger than the input
410  * value, a carry out bit is also returned. The caller may be able to
411  * prove that the carry out is always zero, in which case it may be
412  * safely ignored.
413  *
414  * The upper half of the output value (i.e. t) will also be copied to
415  * the result pointer. It is permissible for the result pointer to
416  * overlap the lower half of the input value.
417  *
418  * External knowledge of constraints on the modulus and the input
419  * value may be used to prove constraints on the result. The
420  * constraint on the modulus may be generally expressed as
421  *
422  * R > kN
423  *
424  * for some positive integer k. The value k=1 is allowed, and simply
425  * expresses that the modulus fits within the number of bits in its
426  * own representation.
427  *
428  * For classic Montgomery reduction, we have k=1, i.e. R > N and a
429  * separate constraint that the input value is in the range x < RN.
430  * This gives the result constraint
431  *
432  * tR < RN + (R-1)N
433  * < 2RN - N
434  * < 2RN
435  * t < 2N
436  *
437  * A single subtraction of the modulus may therefore be required to
438  * bring it into the range t < N.
439  *
440  * When the input value is known to be a product of two integers A and
441  * B, with A < aN and B < bN, we get the result constraint
442  *
443  * tR < abN^2 + (R-1)N
444  * < (ab/k)RN + RN - N
445  * < (1 + ab/k)RN
446  * t < (1 + ab/k)N
447  *
448  * If we have k=a=b=1, i.e. R > N with A < N and B < N, then the
449  * result is in the range t < 2N and may require a single subtraction
450  * of the modulus to bring it into the range t < N so that it may be
451  * used as an input on a subsequent iteration.
452  *
453  * If we have k=4 and a=b=2, i.e. R > 4N with A < 2N and B < 2N, then
454  * the result is in the range t < 2N and may immediately be used as an
455  * input on a subsequent iteration, without requiring a subtraction.
456  *
457  * Larger values of k may be used to allow for larger values of a and
458  * b, which can be useful to elide intermediate reductions in a
459  * calculation chain that involves additions and subtractions between
460  * multiplications (as used in elliptic curve point addition, for
461  * example). As a general rule: each intermediate addition or
462  * subtraction will require k to be doubled.
463  *
464  * When the input value is known to be a single integer A, with A < aN
465  * (as used when converting out of Montgomery form), we get the result
466  * constraint
467  *
468  * tR < aN + (R-1)N
469  * < RN + (a-1)N
470  *
471  * If we have a=1, i.e. A < N, then the constraint becomes
472  *
473  * tR < RN
474  * t < N
475  *
476  * and so the result is immediately in the range t < N with no
477  * subtraction of the modulus required.
478  *
479  * For any larger value of a, the result value t=N becomes possible.
480  * Additional external knowledge may potentially be used to prove that
481  * t=N cannot occur. For example: if the caller is performing modular
482  * exponentiation with a prime modulus (or, more generally, a modulus
483  * that is coprime to the base), then there is no way for a non-zero
484  * base value to end up producing an exact multiple of the modulus.
485  * If t=N cannot be disproved, then conversion out of Montgomery form
486  * may require an additional subtraction of the modulus.
487  */
490  bigint_element_t *result0,
491  unsigned int size ) {
492  const bigint_t ( size ) __attribute__ (( may_alias ))
493  *modulus = ( ( const void * ) modulus0 );
494  union {
495  bigint_t ( size * 2 ) full;
496  struct {
497  bigint_t ( size ) low;
498  bigint_t ( size ) high;
499  } __attribute__ (( packed ));
500  } __attribute__ (( may_alias )) *value = ( ( void * ) value0 );
501  bigint_t ( size ) __attribute__ (( may_alias ))
502  *result = ( ( void * ) result0 );
503  static bigint_t ( 1 ) cached;
504  static bigint_t ( 1 ) negmodinv;
505  bigint_element_t multiple;
507  unsigned int i;
508  unsigned int j;
509  int overflow;
510 
511  /* Sanity checks */
512  assert ( bigint_bit_is_set ( modulus, 0 ) );
513 
514  /* Calculate inverse (or use cached version) */
515  if ( cached.element[0] != modulus->element[0] ) {
516  bigint_mod_invert ( modulus, &negmodinv );
517  negmodinv.element[0] = -negmodinv.element[0];
518  cached.element[0] = modulus->element[0];
519  }
520 
521  /* Perform multiprecision Montgomery reduction */
522  for ( i = 0 ; i < size ; i++ ) {
523 
524  /* Determine scalar multiple for this round */
525  multiple = ( value->low.element[i] * negmodinv.element[0] );
526 
527  /* Multiply value to make it divisible by 2^(width*i) */
528  carry = 0;
529  for ( j = 0 ; j < size ; j++ ) {
530  bigint_multiply_one ( multiple, modulus->element[j],
531  &value->full.element[ i + j ],
532  &carry );
533  }
534 
535  /* Since value is now divisible by 2^(width*i), we
536  * know that the current low element must have been
537  * zeroed.
538  */
539  assert ( value->low.element[i] == 0 );
540 
541  /* Store the multiplication carry out in the result,
542  * avoiding the need to immediately propagate the
543  * carry through the remaining elements.
544  */
545  result->element[i] = carry;
546  }
547 
548  /* Add the accumulated carries */
549  overflow = bigint_add ( result, &value->high );
550 
551  /* Copy to result buffer */
552  bigint_copy ( &value->high, result );
553 
554  return overflow;
555 }
556 
557 /**
558  * Perform classic Montgomery reduction (REDC) of a big integer
559  *
560  * @v modulus0 Element 0 of big integer odd modulus
561  * @v value0 Element 0 of big integer to be reduced
562  * @v result0 Element 0 of big integer to hold result
563  * @v size Number of elements in modulus and result
564  */
567  bigint_element_t *result0,
568  unsigned int size ) {
569  const bigint_t ( size ) __attribute__ (( may_alias ))
570  *modulus = ( ( const void * ) modulus0 );
571  union {
572  bigint_t ( size * 2 ) full;
573  struct {
574  bigint_t ( size ) low;
575  bigint_t ( size ) high;
576  } __attribute__ (( packed ));
577  } __attribute__ (( may_alias )) *value = ( ( void * ) value0 );
578  bigint_t ( size ) __attribute__ (( may_alias ))
579  *result = ( ( void * ) result0 );
580  int overflow;
581  int underflow;
582 
583  /* Sanity check */
584  assert ( ! bigint_is_geq ( &value->high, modulus ) );
585 
586  /* Perform relaxed Montgomery reduction */
587  overflow = bigint_montgomery_relaxed ( modulus, &value->full, result );
588 
589  /* Conditionally subtract the modulus once */
590  underflow = bigint_subtract ( modulus, result );
591  bigint_swap ( result, &value->high, ( underflow & ~overflow ) );
592 
593  /* Sanity check */
594  assert ( ! bigint_is_geq ( result, modulus ) );
595 }
596 
597 /**
598  * Perform generalised exponentiation via a Montgomery ladder
599  *
600  * @v result0 Element 0 of result (initialised to identity element)
601  * @v multiple0 Element 0 of multiple (initialised to generator)
602  * @v size Number of elements in result and multiple
603  * @v exponent0 Element 0 of exponent
604  * @v exponent_size Number of elements in exponent
605  * @v op Montgomery ladder commutative operation
606  * @v ctx Operation context (if needed)
607  * @v tmp Temporary working space (if needed)
608  *
609  * The Montgomery ladder may be used to perform any operation that is
610  * isomorphic to exponentiation, i.e. to compute the result
611  *
612  * r = g^e = g * g * g * g * .... * g
613  *
614  * for an arbitrary commutative operation "*", generator "g" and
615  * exponent "e".
616  *
617  * The result "r" is computed in constant time (assuming that the
618  * underlying operation is constant time) in k steps, where k is the
619  * number of bits in the big integer representation of the exponent.
620  *
621  * The result "r" must be initialised to the operation's identity
622  * element, and the multiple must be initialised to the generator "g".
623  * On exit, the multiple will contain
624  *
625  * m = r * g = g^(e+1)
626  *
627  * Note that the terminology used here refers to exponentiation
628  * defined as repeated multiplication, but that the ladder may equally
629  * well be used to perform any isomorphic operation (such as
630  * multiplication defined as repeated addition).
631  */
633  bigint_element_t *multiple0, unsigned int size,
634  const bigint_element_t *exponent0,
635  unsigned int exponent_size, bigint_ladder_op_t *op,
636  const void *ctx, void *tmp ) {
637  bigint_t ( size ) __attribute__ (( may_alias ))
638  *result = ( ( void * ) result0 );
639  bigint_t ( size ) __attribute__ (( may_alias ))
640  *multiple = ( ( void * ) multiple0 );
641  const bigint_t ( exponent_size ) __attribute__ (( may_alias ))
642  *exponent = ( ( const void * ) exponent0 );
643  const unsigned int width = ( 8 * sizeof ( bigint_element_t ) );
644  unsigned int bit = ( exponent_size * width );
645  int toggle = 0;
646  int previous;
647 
648  /* We have two physical storage locations: Rres (the "result"
649  * register) and Rmul (the "multiple" register).
650  *
651  * On entry we have:
652  *
653  * Rres = g^0 = 1 (the identity element)
654  * Rmul = g (the generator)
655  *
656  * For calculation purposes, define two virtual registers R[0]
657  * and R[1], mapped to the underlying physical storage
658  * locations via a boolean toggle state "t":
659  *
660  * R[t] -> Rres
661  * R[~t] -> Rmul
662  *
663  * Define the initial toggle state to be t=0, so that we have:
664  *
665  * R[0] = g^0 = 1 (the identity element)
666  * R[1] = g (the generator)
667  *
668  * The Montgomery ladder then iterates over each bit "b" of
669  * the exponent "e" (from MSB down to LSB), computing:
670  *
671  * R[1] := R[0] * R[1], R[0] := R[0] * R[0] (if b=0)
672  * R[0] := R[1] * R[0], R[1] := R[1] * R[1] (if b=1)
673  *
674  * i.e.
675  *
676  * R[~b] := R[b] * R[~b], R[b] := R[b] * R[b]
677  *
678  * To avoid data-dependent memory access patterns, we
679  * implement this as:
680  *
681  * Rmul := Rres * Rmul
682  * Rres := Rres * Rres
683  *
684  * and update the toggle state "t" (via constant-time
685  * conditional swaps) as needed to ensure that R[b] always
686  * maps to Rres and R[~b] always maps to Rmul.
687  */
688  while ( bit-- ) {
689 
690  /* Update toggle state t := b
691  *
692  * If the new toggle state is not equal to the old
693  * toggle state, then we must swap R[0] and R[1] (in
694  * constant time).
695  */
696  previous = toggle;
697  toggle = bigint_bit_is_set ( exponent, bit );
698  bigint_swap ( result, multiple, ( toggle ^ previous ) );
699 
700  /* Calculate Rmul = R[~b] := R[b] * R[~b] = Rres * Rmul */
701  op ( result->element, multiple->element, size, ctx, tmp );
702 
703  /* Calculate Rres = R[b] := R[b] * R[b] = Rres * Rres */
704  op ( result->element, result->element, size, ctx, tmp );
705  }
706 
707  /* Reset toggle state to zero */
708  bigint_swap ( result, multiple, toggle );
709 }
710 
711 /**
712  * Perform modular multiplication as part of a Montgomery ladder
713  *
714  * @v operand Element 0 of first input operand (may overlap result)
715  * @v result Element 0 of second input operand and result
716  * @v size Number of elements in operands and result
717  * @v ctx Operation context (odd modulus, or NULL)
718  * @v tmp Temporary working space
719  */
720 void bigint_mod_exp_ladder ( const bigint_element_t *multiplier0,
721  bigint_element_t *result0, unsigned int size,
722  const void *ctx, void *tmp ) {
723  const bigint_t ( size ) __attribute__ (( may_alias ))
724  *multiplier = ( ( const void * ) multiplier0 );
725  bigint_t ( size ) __attribute__ (( may_alias ))
726  *result = ( ( void * ) result0 );
727  const bigint_t ( size ) __attribute__ (( may_alias ))
728  *modulus = ( ( const void * ) ctx );
729  bigint_t ( size * 2 ) __attribute__ (( may_alias ))
730  *product = ( ( void * ) tmp );
731 
732  /* Multiply and reduce */
734  if ( modulus ) {
735  bigint_montgomery ( modulus, product, result );
736  } else {
738  }
739 }
740 
741 /**
742  * Perform modular exponentiation of big integers
743  *
744  * @v base0 Element 0 of big integer base
745  * @v modulus0 Element 0 of big integer modulus
746  * @v exponent0 Element 0 of big integer exponent
747  * @v result0 Element 0 of big integer to hold result
748  * @v size Number of elements in base, modulus, and result
749  * @v exponent_size Number of elements in exponent
750  * @v tmp Temporary working space
751  */
753  const bigint_element_t *modulus0,
754  const bigint_element_t *exponent0,
755  bigint_element_t *result0,
756  unsigned int size, unsigned int exponent_size,
757  void *tmp ) {
758  const bigint_t ( size ) __attribute__ (( may_alias )) *base =
759  ( ( const void * ) base0 );
760  const bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
761  ( ( const void * ) modulus0 );
762  const bigint_t ( exponent_size ) __attribute__ (( may_alias ))
763  *exponent = ( ( const void * ) exponent0 );
764  bigint_t ( size ) __attribute__ (( may_alias )) *result =
765  ( ( void * ) result0 );
766  const unsigned int width = ( 8 * sizeof ( bigint_element_t ) );
767  struct {
768  struct {
769  bigint_t ( size ) modulus;
770  bigint_t ( size ) stash;
771  };
772  union {
773  bigint_t ( 2 * size ) full;
774  bigint_t ( size ) low;
775  } product;
776  } *temp = tmp;
777  const uint8_t one[1] = { 1 };
778  bigint_element_t submask;
779  unsigned int subsize;
780  unsigned int scale;
781  unsigned int i;
782 
783  /* Sanity check */
784  assert ( sizeof ( *temp ) == bigint_mod_exp_tmp_len ( modulus ) );
785 
786  /* Handle degenerate case of zero modulus */
787  if ( ! bigint_max_set_bit ( modulus ) ) {
788  memset ( result, 0, sizeof ( *result ) );
789  return;
790  }
791 
792  /* Factor modulus as (N * 2^scale) where N is odd */
793  bigint_copy ( modulus, &temp->modulus );
794  for ( scale = 0 ; ( ! bigint_bit_is_set ( &temp->modulus, 0 ) ) ;
795  scale++ ) {
796  bigint_shr ( &temp->modulus );
797  }
798  subsize = ( ( scale + width - 1 ) / width );
799  submask = ( ( 1UL << ( scale % width ) ) - 1 );
800  if ( ! submask )
801  submask = ~submask;
802 
803  /* Calculate (R^2 mod N) */
804  bigint_reduce ( &temp->modulus, &temp->stash );
805 
806  /* Initialise result = Montgomery(1, R^2 mod N) */
807  bigint_grow ( &temp->stash, &temp->product.full );
808  bigint_montgomery ( &temp->modulus, &temp->product.full, result );
809 
810  /* Convert base into Montgomery form */
811  bigint_multiply ( base, &temp->stash, &temp->product.full );
812  bigint_montgomery ( &temp->modulus, &temp->product.full,
813  &temp->stash );
814 
815  /* Calculate x1 = base^exponent modulo N */
816  bigint_ladder ( result, &temp->stash, exponent, bigint_mod_exp_ladder,
817  &temp->modulus, &temp->product );
818 
819  /* Convert back out of Montgomery form */
820  bigint_grow ( result, &temp->product.full );
821  bigint_montgomery_relaxed ( &temp->modulus, &temp->product.full,
822  result );
823 
824  /* Handle even moduli via Garner's algorithm */
825  if ( subsize ) {
826  const bigint_t ( subsize ) __attribute__ (( may_alias ))
827  *subbase = ( ( const void * ) base );
828  bigint_t ( subsize ) __attribute__ (( may_alias ))
829  *submodulus = ( ( void * ) &temp->modulus );
830  bigint_t ( subsize ) __attribute__ (( may_alias ))
831  *substash = ( ( void * ) &temp->stash );
832  bigint_t ( subsize ) __attribute__ (( may_alias ))
833  *subresult = ( ( void * ) result );
834  union {
835  bigint_t ( 2 * subsize ) full;
836  bigint_t ( subsize ) low;
837  } __attribute__ (( may_alias ))
838  *subproduct = ( ( void * ) &temp->product.full );
839 
840  /* Calculate x2 = base^exponent modulo 2^k */
841  bigint_init ( substash, one, sizeof ( one ) );
842  bigint_copy ( subbase, submodulus );
843  bigint_ladder ( substash, submodulus, exponent,
844  bigint_mod_exp_ladder, NULL, subproduct );
845 
846  /* Reconstruct N */
847  bigint_copy ( modulus, &temp->modulus );
848  for ( i = 0 ; i < scale ; i++ )
849  bigint_shr ( &temp->modulus );
850 
851  /* Calculate N^-1 modulo 2^k */
852  bigint_mod_invert ( submodulus, &subproduct->low );
853  bigint_copy ( &subproduct->low, submodulus );
854 
855  /* Calculate y = (x2 - x1) * N^-1 modulo 2^k */
856  bigint_subtract ( subresult, substash );
857  bigint_multiply ( substash, submodulus, &subproduct->full );
858  subproduct->low.element[ subsize - 1 ] &= submask;
859  bigint_grow ( &subproduct->low, &temp->stash );
860 
861  /* Reconstruct N */
862  bigint_mod_invert ( submodulus, &subproduct->low );
863  bigint_copy ( &subproduct->low, submodulus );
864 
865  /* Calculate x = x1 + N * y */
866  bigint_multiply ( &temp->modulus, &temp->stash,
867  &temp->product.full );
868  bigint_add ( &temp->product.low, result );
869  }
870 }
#define __attribute__(x)
Definition: compiler.h:10
uint32_t base
Base.
Definition: librm.h:138
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
uint32_t low
Low 16 bits of address.
Definition: myson.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:752
#define max(x, y)
Definition: ath.h:41
#define bigint_max_set_bit(value)
Find highest bit set in big integer.
Definition: bigint.h:199
int carry
Definition: bigint.h:68
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
#define sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition: stdio.h:37
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define bigint_grow(source, dest)
Grow big integer.
Definition: bigint.h:209
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
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)
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define bigint_montgomery_relaxed(modulus, value, result)
Perform relaxed Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:300
value element[index]
Definition: bigint.h:398
static uint32_t * value0
Definition: bigint.h:61
Big integer support.
static u32 xor(u32 a, u32 b)
Definition: tlan.h:457
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
unsigned long tmp
Definition: linux_pci.h:65
#define bigint_is_geq(value, reference)
Compare big integers.
Definition: bigint.h:145
#define bigint_mod_invert(invertend, inverse)
Compute inverse of odd big integer modulo any power of two.
Definition: bigint.h:286
Assertions.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define bigint_shr(value)
Shift big integer right.
Definition: bigint.h:122
#define bigint_shrink(source, dest)
Shrink big integer.
Definition: bigint.h:222
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:235
uint32_t bigint_element_t
Element of a big integer.
Definition: bigint.h:16
static unsigned int count
Number of entries.
Definition: dwmac.h:225
uint32_t high
High 32 bits of address.
Definition: myson.h:20
FILE_SECBOOT(PERMITTED)
unsigned char uint8_t
Definition: stdint.h:10
#define bigint_swap(first, second, swap)
Conditionally swap big integers (in constant time)
Definition: bigint.h:247
unsigned char byte
Definition: smc9000.h:38
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
uint16_t result
Definition: hyperv.h:33
#define bigint_shl(value)
Shift big integer left.
Definition: bigint.h:111
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:314
static const uint32_t multiplier
Port multiplier number.
Definition: bigint.h:335
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
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:260
#define bigint_reduce(modulus, result)
Reduce big integer R^2 modulo N.
Definition: bigint.h:274
uint8_t product
Product string.
Definition: smbios.h:17
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition: bigint.h:330
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
const char * bigint_ntoa_raw(const bigint_element_t *value0, unsigned int size)
Transcribe big integer (for debugging)
Definition: bigint.c:48
#define bigint_bit_is_set(value, bit)
Test if bit is set in big integer.
Definition: bigint.h:179
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:99
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
#define bigint_mod_exp_tmp_len(modulus)
Calculate temporary working space required for moduluar exponentiation.
Definition: bigint.h:361
#define bigint_add(addend, value)
Add big integers.
Definition: bigint.h:87
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
String functions.
#define bigint_set_bit(value, bit)
Set bit in big integer.
Definition: bigint.h:156
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
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.
#define BIGINT_NTOA_LSB_MIN
Minimum number of least significant bytes included in transcription.
Definition: bigint.c:39
void * memset(void *dest, int character, size_t len) __nonnull
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