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 <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 */
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;
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 ) {
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 */
118void 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 */
189void 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 */
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 */
720void 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 NULL
NULL pointer (VOID *)
Definition Base.h:322
struct golan_eq_context ctx
Definition CIB_PRM.h:0
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:335
uint32_t bigint_element_t
Element of a big integer.
Definition bigint.h:16
int carry
Definition bigint.h:68
static uint32_t * value0
Definition bigint.h:61
Assertions.
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#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:752
int bigint_montgomery_relaxed_raw(const bigint_element_t *modulus0, bigint_element_t *value0, bigint_element_t *result0, unsigned int size)
Perform relaxed Montgomery reduction (REDC) of a big integer.
Definition bigint.c:488
void bigint_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
const char * bigint_ntoa_raw(const bigint_element_t *value0, unsigned int size)
Transcribe big integer (for debugging)
Definition bigint.c:48
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
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
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
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
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
#define BIGINT_NTOA_LSB_MIN
Minimum number of least significant bytes included in transcription.
Definition bigint.c:39
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
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:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define __attribute__(x)
Definition compiler.h:10
Big integer support.
#define bigint_grow(source, dest)
Grow big integer.
Definition bigint.h:209
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition bigint.h:330
#define bigint_bit_is_set(value, bit)
Test if bit is set in big integer.
Definition bigint.h:179
#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
#define bigint_mod_exp_tmp_len(modulus)
Calculate temporary working space required for moduluar exponentiation.
Definition bigint.h:361
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:156
#define bigint_reduce(modulus, result)
Reduce big integer R^2 modulo N.
Definition bigint.h:274
#define bigint_shl(value)
Shift big integer left.
Definition bigint.h:111
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition bigint.h:99
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition bigint.h:314
#define bigint_shrink(source, dest)
Shrink big integer.
Definition bigint.h:222
static unsigned int unsigned int bit
Definition bigint.h:392
#define bigint_mod_invert(invertend, inverse)
Compute inverse of odd big integer modulo any power of two.
Definition bigint.h:286
#define bigint_max_set_bit(value)
Find highest bit set in big integer.
Definition bigint.h:199
#define bigint_copy(source, dest)
Copy big integer.
Definition bigint.h:235
#define bigint_is_geq(value, reference)
Compare big integers.
Definition bigint.h:145
#define bigint_t(size)
Define a big-integer type.
Definition bigint.h:20
#define bigint_shr(value)
Shift big integer right.
Definition bigint.h:122
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition bigint.h:260
#define bigint_add(addend, value)
Add big integers.
Definition bigint.h:87
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
#define bigint_swap(first, second, swap)
Conditionally swap big integers (in constant time)
Definition bigint.h:247
#define bigint_init(value, data, len)
Initialise big integer.
Definition bigint.h:62
uint8_t product
Product string.
Definition smbios.h:5
String functions.
void * memset(void *dest, int character, size_t len) __nonnull
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