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