2 * Copyright (C) 2017 Denys Vlasenko
4 * Licensed under GPLv2, see file LICENSE in this source tree.
8 /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/.
9 * Changes are flagged with //bbox
14 * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master)
16 * Multiprecision number implementation.
19 * Copyright (c) 2013-2015 INSIDE Secure Corporation
20 * Copyright (c) PeerSec Networks, 2002-2011
23 * The latest version of this code is available at http://www.matrixssl.org
25 * This software is open source; you can redistribute it and/or modify
26 * it under the terms of the GNU General Public License as published by
27 * the Free Software Foundation; either version 2 of the License, or
28 * (at your option) any later version.
30 * This General Public License does NOT permit incorporating this software
31 * into proprietary programs. If you are unable to comply with the GPL, a
32 * commercial license for this software may be purchased from INSIDE at
33 * http://www.insidesecure.com/eng/Company/Locations
35 * This program is distributed in WITHOUT ANY WARRANTY; without even the
36 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
37 * See the GNU General Public License for more details.
39 * You should have received a copy of the GNU General Public License
40 * along with this program; if not, write to the Free Software
41 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
42 * http://www.gnu.org/copyleft/gpl.html
44 /******************************************************************************/
47 //#include "../cryptoApi.h"
50 static int32 pstm_mul_2d(pstm_int *a, int b, pstm_int *c); //bbox: was int16 b
52 /******************************************************************************/
54 init an pstm_int for a given size
56 int32 pstm_init_size(psPool_t *pool, pstm_int * a, uint32 size)
64 a->dp = xzalloc(sizeof (pstm_digit) * size);//bbox
65 //bbox a->pool = pool;
73 // for (x = 0; x < size; x++) {
79 /******************************************************************************/
83 int32 pstm_init(psPool_t *pool, pstm_int * a)
88 allocate memory required and clear it
90 a->dp = xzalloc(sizeof (pstm_digit) * PSTM_DEFAULT_INIT);//bbox
92 set the digits to zero
95 // for (i = 0; i < PSTM_DEFAULT_INIT; i++) {
99 set the used to zero, allocated digits to the default precision and sign
102 //bbox a->pool = pool;
104 a->alloc = PSTM_DEFAULT_INIT;
110 /******************************************************************************/
114 int32 pstm_grow(pstm_int * a, int size)
116 int i; //bbox: was int16
120 If the alloc size is smaller alloc more ram.
122 if (a->alloc < size) {
124 Reallocate the array a->dp
126 We store the return in a temporary variable in case the operation
127 failed we don't want to overwrite the dp member of a.
129 tmp = xrealloc(a->dp, sizeof (pstm_digit) * size);//bbox
131 reallocation succeeded so set a->dp
139 for (; i < a->alloc; i++) {
146 /******************************************************************************/
148 copy, b = a (b must be pre-allocated)
150 int32 pstm_copy(pstm_int * a, pstm_int * b)
155 If dst == src do nothing
163 if (b->alloc < a->used) {
164 if ((res = pstm_grow (b, a->used)) != PSTM_OKAY) {
169 Zero b and copy the parameters over
172 register pstm_digit *tmpa, *tmpb;
174 /* pointer aliases */
181 /* copy all the digits */
182 for (n = 0; n < a->used; n++) {
186 /* clear high digits */
187 for (; n < b->used; n++) {
192 copy used count and sign
199 /******************************************************************************/
203 This is used to ensure that leading zero digits are trimed and the
204 leading "used" digit will be non-zero. Typically very fast. Also fixes
205 the sign if there are no more leading digits
207 void pstm_clamp(pstm_int * a)
209 /* decrease used while the most significant digit is zero. */
210 while (a->used > 0 && a->dp[a->used - 1] == 0) {
213 /* reset the sign flag if used == 0 */
219 /******************************************************************************/
223 void pstm_clear(pstm_int * a)
227 only do anything if a hasn't been freed previously
229 if (a != NULL && a->dp != NULL) {
231 first zero the digits
233 for (i = 0; i < a->used; i++) {
237 psFree (a->dp, a->pool);
239 reset members to make debugging easier
242 a->alloc = a->used = 0;
247 /******************************************************************************/
251 void pstm_clear_multi(pstm_int *mp0, pstm_int *mp1, pstm_int *mp2,
252 pstm_int *mp3, pstm_int *mp4, pstm_int *mp5,
253 pstm_int *mp6, pstm_int *mp7)
255 int32 n; /* Number of ok inits */
257 pstm_int *tempArray[9];
269 for (n = 0; tempArray[n] != NULL; n++) {
270 if ((tempArray[n] != NULL) && (tempArray[n]->dp != NULL)) {
271 pstm_clear(tempArray[n]);
276 /******************************************************************************/
280 void pstm_zero(pstm_int * a)
289 for (n = 0; n < a->alloc; n++) {
295 /******************************************************************************/
297 Compare maginitude of two ints (unsigned).
299 int32 pstm_cmp_mag(pstm_int * a, pstm_int * b)
301 int n; //bbox: was int16
302 pstm_digit *tmpa, *tmpb;
305 compare based on # of non-zero digits
307 if (a->used > b->used) {
311 if (a->used < b->used) {
316 tmpa = a->dp + (a->used - 1);
319 tmpb = b->dp + (a->used - 1);
322 compare based on digits
324 for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
335 /******************************************************************************/
337 Compare two ints (signed)
339 int32 pstm_cmp(pstm_int * a, pstm_int * b)
342 compare based on sign
344 if (a->sign != b->sign) {
345 if (a->sign == PSTM_NEG) {
354 if (a->sign == PSTM_NEG) {
355 /* if negative compare opposite direction */
356 return pstm_cmp_mag(b, a);
358 return pstm_cmp_mag(a, b);
362 /******************************************************************************/
364 pstm_ints can be initialized more precisely when they will populated
365 using pstm_read_unsigned_bin since the length of the byte stream is known
367 int32 pstm_init_for_read_unsigned_bin(psPool_t *pool, pstm_int *a, uint32 len)
371 Need to set this based on how many words max it will take to store the bin.
373 1 to round up for the remainder of this integer math
374 1 for the initial carry of '1' bits that fall between DIGIT_BIT and 8
376 size = (((len / sizeof(pstm_digit)) * (sizeof(pstm_digit) * CHAR_BIT))
378 return pstm_init_size(pool, a, size);
382 /******************************************************************************/
384 Reads a unsigned char array into pstm_int format. User should have
385 called pstm_init_for_read_unsigned_bin first. There is some grow logic
386 here if the default pstm_init was used but we don't really want to hit it.
388 int32 pstm_read_unsigned_bin(pstm_int *a, unsigned char *b, int32 c)
394 If we know the endianness of this architecture, and we're using
395 32-bit pstm_digits, we can optimize this
397 #if (defined(ENDIAN_LITTLE) || defined(ENDIAN_BIG)) && !defined(PSTM_64BIT)
398 /* But not for both simultaneously */
399 #if defined(ENDIAN_LITTLE) && defined(ENDIAN_BIG)
400 #error Both ENDIAN_LITTLE and ENDIAN_BIG defined.
404 if ((unsigned)c > (PSTM_MAX_SIZE * sizeof(pstm_digit))) {
405 uint32 excess = c - (PSTM_MAX_SIZE * sizeof(pstm_digit));
409 a->used = ((c + sizeof(pstm_digit) - 1)/sizeof(pstm_digit));
410 if (a->alloc < a->used) {
411 if (pstm_grow(a, a->used) != PSTM_OKAY) {
415 pd = (unsigned char *)a->dp;
416 /* read the bytes in */
419 /* Use Duff's device to unroll the loop. */
420 int32 idx = (c - 1) & ~3;
422 case 0: do { pd[idx+0] = *b++;
423 case 3: pd[idx+1] = *b++;
424 case 2: pd[idx+2] = *b++;
425 case 1: pd[idx+3] = *b++;
427 } while ((c -= 4) > 0);
431 for (c -= 1; c >= 0; c -= 1) {
437 /* Big enough based on the len? */
438 a->used = (((c / sizeof(pstm_digit)) * (sizeof(pstm_digit) * CHAR_BIT))
441 if (a->alloc < a->used) {
442 if (pstm_grow(a, a->used) != PSTM_OKAY) {
446 /* read the bytes in */
448 if (pstm_mul_2d (a, 8, a) != PSTM_OKAY) {
460 /******************************************************************************/
463 int pstm_count_bits (pstm_int * a)
465 int r; //bbox: was int16
472 /* get number of digits and add that */
473 r = (a->used - 1) * DIGIT_BIT;
475 /* take the last digit and count the bits in it */
476 q = a->dp[a->used - 1];
477 while (q > ((pstm_digit) 0)) {
479 q >>= ((pstm_digit) 1);
484 /******************************************************************************/
485 int32 pstm_unsigned_bin_size(pstm_int *a)
487 int32 size = pstm_count_bits (a);
488 return (size / 8 + ((size & 7) != 0 ? 1 : 0));
491 /******************************************************************************/
492 void pstm_set(pstm_int *a, pstm_digit b)
496 a->used = a->dp[0] ? 1 : 0;
499 /******************************************************************************/
503 void pstm_rshd(pstm_int *a, int x)
505 int y; //bbox: was int16
507 /* too many digits just zero and return */
514 for (y = 0; y < a->used - x; y++) {
515 a->dp[y] = a->dp[y+x];
519 for (; y < a->used; y++) {
523 /* decrement count */
528 /******************************************************************************/
530 Shift left a certain amount of digits.
532 int32 pstm_lshd(pstm_int * a, int b)
534 int x; //bbox: was int16
538 If its less than zero return.
544 Grow to fit the new digits.
546 if (a->alloc < a->used + b) {
547 if ((res = pstm_grow (a, a->used + b)) != PSTM_OKAY) {
553 register pstm_digit *top, *bottom;
555 Increment the used by the shift amount then copy upwards.
560 top = a->dp + a->used - 1;
563 bottom = a->dp + a->used - 1 - b;
565 This is implemented using a sliding window except the window goes the
566 other way around. Copying from the bottom to the top.
568 for (x = a->used - 1; x >= b; x--) {
572 /* zero the lower digits */
574 for (x = 0; x < b; x++) {
581 /******************************************************************************/
585 int32 pstm_2expt(pstm_int *a, int b)
587 int z; //bbox: was int16
589 /* zero a as per default */
597 if (z >= PSTM_MAX_SIZE) {
598 return PS_LIMIT_FAIL;
601 /* set the used count of where the bit will go */
604 if (a->used > a->alloc) {
605 if (pstm_grow(a, a->used) != PSTM_OKAY) {
610 /* put the single bit in its place */
611 a->dp[z] = ((pstm_digit)1) << (b % DIGIT_BIT);
615 /******************************************************************************/
619 int32 pstm_mul_2(pstm_int * a, pstm_int * b)
622 int x, oldused; //bbox: was int16
625 grow to accomodate result
627 if (b->alloc < a->used + 1) {
628 if ((res = pstm_grow (b, a->used + 1)) != PSTM_OKAY) {
636 register pstm_digit r, rr, *tmpa, *tmpb;
638 /* alias for source */
646 for (x = 0; x < a->used; x++) {
648 get what will be the *next* carry bit from the
649 MSB of the current digit
651 rr = *tmpa >> ((pstm_digit)(DIGIT_BIT - 1));
653 now shift up this digit, add in the carry [from the previous]
655 *tmpb++ = ((*tmpa++ << ((pstm_digit)1)) | r);
657 copy the carry that would be from the source
658 digit into the next iteration
663 /* new leading digit? */
664 if (r != 0 && b->used != (PSTM_MAX_SIZE-1)) {
665 /* add a MSB which is always 1 at this point */
670 now zero any excess digits on the destination that we didn't write to
672 tmpb = b->dp + b->used;
673 for (x = b->used; x < oldused; x++) {
681 /******************************************************************************/
683 unsigned subtraction ||a|| >= ||b|| ALWAYS!
685 int32 s_pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c)
687 int oldbused, oldused; //bbox: was int16
691 if (b->used > a->used) {
692 return PS_LIMIT_FAIL;
694 if (c->alloc < a->used) {
695 if ((x = pstm_grow (c, a->used)) != PSTM_OKAY) {
704 for (x = 0; x < oldbused; x++) {
705 t = ((pstm_word)a->dp[x]) - (((pstm_word)b->dp[x]) + t);
706 c->dp[x] = (pstm_digit)t;
707 t = (t >> DIGIT_BIT)&1;
709 for (; x < a->used; x++) {
710 t = ((pstm_word)a->dp[x]) - t;
711 c->dp[x] = (pstm_digit)t;
712 t = (t >> DIGIT_BIT);
714 for (; x < oldused; x++) {
721 /******************************************************************************/
725 static int32 s_pstm_add(pstm_int *a, pstm_int *b, pstm_int *c)
727 int x, y, oldused; //bbox: was int16
728 register pstm_word t, adp, bdp;
737 if (c->used > c->alloc) {
738 if (pstm_grow(c, c->used) != PSTM_OKAY) {
744 for (x = 0; x < y; x++) {
748 adp = (pstm_word)a->dp[x];
753 bdp = (pstm_word)b->dp[x];
756 c->dp[x] = (pstm_digit)t;
759 if (t != 0 && x < PSTM_MAX_SIZE) {
760 if (c->used == c->alloc) {
761 if (pstm_grow(c, c->alloc + 1) != PSTM_OKAY) {
765 c->dp[c->used++] = (pstm_digit)t;
770 for (; x < oldused; x++) {
778 /******************************************************************************/
782 int32 pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c)
785 int sa, sb; //bbox: was int16
792 subtract a negative from a positive, OR a positive from a negative.
793 For both, ADD their magnitudes, and use the sign of the first number.
796 if ((res = s_pstm_add (a, b, c)) != PSTM_OKAY) {
801 subtract a positive from a positive, OR a negative from a negative.
802 First, take the difference between their magnitudes, then...
804 if (pstm_cmp_mag (a, b) != PSTM_LT) {
805 /* Copy the sign from the first */
807 /* The first has a larger or equal magnitude */
808 if ((res = s_pstm_sub (a, b, c)) != PSTM_OKAY) {
812 /* The result has the _opposite_ sign from the first number. */
813 c->sign = (sa == PSTM_ZPOS) ? PSTM_NEG : PSTM_ZPOS;
814 /* The second has a larger magnitude */
815 if ((res = s_pstm_sub (b, a, c)) != PSTM_OKAY) {
823 /******************************************************************************/
827 int32 pstm_sub_d(psPool_t *pool, pstm_int *a, pstm_digit b, pstm_int *c)
832 if (pstm_init_size(pool, &tmp, sizeof(pstm_digit)) != PSTM_OKAY) {
836 res = pstm_sub(a, &tmp, c);
841 /******************************************************************************/
843 setups the montgomery reduction
845 int32 pstm_montgomery_setup(pstm_int *a, pstm_digit *rho)
850 fast inversion mod 2**k
851 Based on the fact that
852 XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
853 => 2*X*A - X*X*A*A = 1
859 psTraceCrypto("pstm_montogomery_setup failure\n");
863 x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
864 x *= 2 - b * x; /* here x*a==1 mod 2**8 */
865 x *= 2 - b * x; /* here x*a==1 mod 2**16 */
866 x *= 2 - b * x; /* here x*a==1 mod 2**32 */
868 x *= 2 - b * x; /* here x*a==1 mod 2**64 */
870 /* rho = -1/m mod b */
871 *rho = (pstm_digit)(((pstm_word) 1 << ((pstm_word) DIGIT_BIT)) -
876 /******************************************************************************/
878 * computes a = B**n mod b without division or multiplication useful for
879 * normalizing numbers in a Montgomery system.
881 int32 pstm_montgomery_calc_normalization(pstm_int *a, pstm_int *b)
884 int bits; //bbox: was int16
886 /* how many bits of last digit does b use */
887 bits = pstm_count_bits (b) % DIGIT_BIT;
888 if (!bits) bits = DIGIT_BIT;
890 /* compute A = B^(n-1) * 2^(bits-1) */
892 if ((x = pstm_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) !=
901 /* now compute C = A * B mod b */
902 for (x = bits - 1; x < (int32)DIGIT_BIT; x++) {
903 if (pstm_mul_2 (a, a) != PSTM_OKAY) {
906 if (pstm_cmp_mag (a, b) != PSTM_LT) {
907 if (s_pstm_sub (a, b, a) != PSTM_OKAY) {
915 /******************************************************************************/
919 static int32 pstm_mul_2d(pstm_int *a, int b, pstm_int *c)
921 pstm_digit carry, carrytmp, shift;
922 int x; //bbox: was int16
925 if (pstm_copy(a, c) != PSTM_OKAY) {
929 /* handle whole digits */
930 if (b >= DIGIT_BIT) {
931 if (pstm_lshd(c, b/DIGIT_BIT) != PSTM_OKAY) {
937 /* shift the digits */
940 shift = DIGIT_BIT - b;
941 for (x = 0; x < c->used; x++) {
942 carrytmp = c->dp[x] >> shift;
943 c->dp[x] = (c->dp[x] << b) + carry;
946 /* store last carry if room */
947 if (carry && x < PSTM_MAX_SIZE) {
948 if (c->used == c->alloc) {
949 if (pstm_grow(c, c->alloc + 1) != PSTM_OKAY) {
953 c->dp[c->used++] = carry;
960 /******************************************************************************/
964 static int32 pstm_mod_2d(pstm_int *a, int b, pstm_int *c) //bbox: was int16 b
966 int x; //bbox: was int16
968 /* zero if count less than or equal to zero */
974 /* get copy of input */
975 if (pstm_copy(a, c) != PSTM_OKAY) {
979 /* if 2**d is larger than we just return */
980 if (b >= (DIGIT_BIT * a->used)) {
984 /* zero digits above the last digit of the modulus */
985 for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++)
989 /* clear the digit that is not completely outside/inside the modulus */
990 c->dp[b / DIGIT_BIT] &= ~((pstm_digit)0) >> (DIGIT_BIT - b);
996 /******************************************************************************/
1000 int32 pstm_mul_d(pstm_int *a, pstm_digit b, pstm_int *c)
1004 int x, oldused; //bbox: was int16
1006 if (c->alloc < a->used + 1) {
1007 if ((res = pstm_grow (c, a->used + 1)) != PSTM_OKAY) {
1015 for (x = 0; x < a->used; x++) {
1016 w = ((pstm_word)a->dp[x]) * ((pstm_word)b) + w;
1017 c->dp[x] = (pstm_digit)w;
1020 if (w != 0 && (a->used != PSTM_MAX_SIZE)) {
1021 c->dp[c->used++] = (pstm_digit)w;
1024 for (; x < oldused; x++) {
1031 /******************************************************************************/
1035 int32 pstm_div_2d(psPool_t *pool, pstm_int *a, int b, pstm_int *c,
1038 pstm_digit D, r, rr;
1040 int x; //bbox: was int16
1043 /* if the shift count is <= 0 then we do no work */
1045 if (pstm_copy (a, c) != PSTM_OKAY) {
1054 /* get the remainder */
1056 if (pstm_init(pool, &t) != PSTM_OKAY) {
1059 if (pstm_mod_2d (a, b, &t) != PSTM_OKAY) {
1066 if (pstm_copy(a, c) != PSTM_OKAY) {
1071 /* shift by as many digits in the bit count */
1072 if (b >= (int32)DIGIT_BIT) {
1073 pstm_rshd (c, b / DIGIT_BIT);
1076 /* shift any bit count < DIGIT_BIT */
1077 D = (pstm_digit) (b % DIGIT_BIT);
1079 register pstm_digit *tmpc, mask, shift;
1082 mask = (((pstm_digit)1) << D) - 1;
1085 shift = DIGIT_BIT - D;
1088 tmpc = c->dp + (c->used - 1);
1092 for (x = c->used - 1; x >= 0; x--) {
1093 /* get the lower bits of this word in a temp */
1096 /* shift the current word and mix in the carry bits from previous */
1097 *tmpc = (*tmpc >> D) | (r << shift);
1100 /* set the carry to the carry bits of the current word above */
1109 if (pstm_copy(&t, d) != PSTM_OKAY) {
1117 /******************************************************************************/
1121 int32 pstm_div_2(pstm_int * a, pstm_int * b)
1123 int x, oldused; //bbox: was int16
1125 if (b->alloc < a->used) {
1126 if (pstm_grow(b, a->used) != PSTM_OKAY) {
1133 register pstm_digit r, rr, *tmpa, *tmpb;
1136 tmpa = a->dp + b->used - 1;
1139 tmpb = b->dp + b->used - 1;
1143 for (x = b->used - 1; x >= 0; x--) {
1144 /* get the carry for the next iteration */
1147 /* shift the current digit, add in carry and store */
1148 *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
1150 /* forward carry to next iteration */
1154 /* zero excess digits */
1155 tmpb = b->dp + b->used;
1156 for (x = b->used; x < oldused; x++) {
1165 /******************************************************************************/
1167 Creates "a" then copies b into it
1169 int32 pstm_init_copy(psPool_t *pool, pstm_int * a, pstm_int * b, int toSqr)
1171 int x; //bbox: was int16
1181 Smart-size: Increasing size of a if b->used is roughly half
1182 of b->alloc because usage has shown that a lot of these copies
1183 go on to be squared and need these extra digits
1185 if ((b->used * 2) + 2 >= x) {
1186 x = (b->used * 2) + 3;
1189 if ((res = pstm_init_size(pool, a, x)) != PSTM_OKAY) {
1192 return pstm_copy(b, a);
1195 /******************************************************************************/
1197 With some compilers, we have seen issues linking with the builtin
1198 64 bit division routine. The issues with either manifest in a failure
1199 to find 'udivdi3' at link time, or a runtime invalid instruction fault
1200 during an RSA operation.
1201 The routine below divides a 64 bit unsigned int by a 32 bit unsigned int
1202 explicitly, rather than using the division operation
1203 The 64 bit result is placed in the 'numerator' parameter
1204 The 32 bit mod (remainder) of the division is the return parameter
1205 Based on implementations by:
1206 Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
1207 Copyright (C) 1999 Hewlett-Packard Co
1208 Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
1210 #if defined(USE_MATRIX_DIV64) && defined(PSTM_32BIT)
1211 static uint32 psDiv64(uint64 *numerator, uint32 denominator)
1213 uint64 rem = *numerator;
1214 uint64 b = denominator;
1217 uint32 high = rem >> 32;
1219 if (high >= denominator) {
1220 high /= denominator;
1221 res = (uint64) high << 32;
1222 rem -= (uint64) (high * denominator) << 32;
1224 while ((int64)b > 0 && b < rem) {
1239 #endif /* USE_MATRIX_DIV64 */
1241 #if defined(USE_MATRIX_DIV128) && defined(PSTM_64BIT)
1242 typedef unsigned long uint128 __attribute__ ((mode(TI)));
1243 static uint64 psDiv128(uint128 *numerator, uint64 denominator)
1245 uint128 rem = *numerator;
1246 uint128 b = denominator;
1249 uint64 high = rem >> 64;
1251 if (high >= denominator) {
1252 high /= denominator;
1253 res = (uint128) high << 64;
1254 rem -= (uint128) (high * denominator) << 64;
1256 while ((uint128)b > 0 && b < rem) {
1271 #endif /* USE_MATRIX_DIV128 */
1273 /******************************************************************************/
1277 int32 pstm_div(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c,
1280 pstm_int q, x, y, t1, t2;
1282 int n, t, i, norm, neg; //bbox: was int16
1284 /* is divisor zero ? */
1285 if (pstm_iszero (b) == 1) {
1286 return PS_LIMIT_FAIL;
1289 /* if a < b then q=0, r = a */
1290 if (pstm_cmp_mag (a, b) == PSTM_LT) {
1292 if (pstm_copy(a, d) != PSTM_OKAY) {
1304 if ((res = pstm_init_size(pool, &t1, a->alloc)) != PSTM_OKAY) {
1307 if ((res = pstm_init_size(pool, &t2, 3)) != PSTM_OKAY) {
1310 if ((res = pstm_init_copy(pool, &x, a, 0)) != PSTM_OKAY) {
1314 Used to be an init_copy on b but pstm_grow was always hit with triple size
1316 if ((res = pstm_init_size(pool, &y, b->used * 3)) != PSTM_OKAY) {
1319 if ((res = pstm_copy(b, &y)) != PSTM_OKAY) {
1324 neg = (a->sign == b->sign) ? PSTM_ZPOS : PSTM_NEG;
1325 x.sign = y.sign = PSTM_ZPOS;
1327 /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
1328 norm = pstm_count_bits(&y) % DIGIT_BIT;
1329 if (norm < (int32)(DIGIT_BIT-1)) {
1330 norm = (DIGIT_BIT-1) - norm;
1331 if ((res = pstm_mul_2d(&x, norm, &x)) != PSTM_OKAY) {
1334 if ((res = pstm_mul_2d(&y, norm, &y)) != PSTM_OKAY) {
1341 /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
1345 if ((res = pstm_init_size(pool, &q, n - t + 1)) != PSTM_OKAY) {
1350 /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
1351 if ((res = pstm_lshd(&y, n - t)) != PSTM_OKAY) { /* y = y*b**{n-t} */
1355 while (pstm_cmp (&x, &y) != PSTM_LT) {
1357 if ((res = pstm_sub(&x, &y, &x)) != PSTM_OKAY) {
1362 /* reset y by shifting it back down */
1363 pstm_rshd (&y, n - t);
1365 /* step 3. for i from n down to (t + 1) */
1366 for (i = n; i >= (t + 1); i--) {
1371 /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
1372 * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
1373 if (x.dp[i] == y.dp[t]) {
1374 q.dp[i - t - 1] = (pstm_digit)((((pstm_word)1) << DIGIT_BIT) - 1);
1377 tmp = ((pstm_word) x.dp[i]) << ((pstm_word) DIGIT_BIT);
1378 tmp |= ((pstm_word) x.dp[i - 1]);
1379 #if defined(USE_MATRIX_DIV64) && defined(PSTM_32BIT)
1380 psDiv64(&tmp, y.dp[t]);
1381 #elif defined(USE_MATRIX_DIV128) && defined(PSTM_64BIT)
1382 psDiv128(&tmp, y.dp[t]);
1384 tmp /= ((pstm_word) y.dp[t]);
1385 #endif /* USE_MATRIX_DIV64 */
1386 q.dp[i - t - 1] = (pstm_digit) (tmp);
1389 /* while (q{i-t-1} * (yt * b + y{t-1})) >
1390 xi * b**2 + xi-1 * b + xi-2
1394 q.dp[i - t - 1] = (q.dp[i - t - 1] + 1);
1396 q.dp[i - t - 1] = (q.dp[i - t - 1] - 1);
1398 /* find left hand */
1400 t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
1403 if ((res = pstm_mul_d (&t1, q.dp[i - t - 1], &t1)) != PSTM_OKAY) {
1407 /* find right hand */
1408 t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
1409 t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
1412 } while (pstm_cmp_mag(&t1, &t2) == PSTM_GT);
1414 /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
1415 if ((res = pstm_mul_d(&y, q.dp[i - t - 1], &t1)) != PSTM_OKAY) {
1419 if ((res = pstm_lshd(&t1, i - t - 1)) != PSTM_OKAY) {
1423 if ((res = pstm_sub(&x, &t1, &x)) != PSTM_OKAY) {
1427 /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
1428 if (x.sign == PSTM_NEG) {
1429 if ((res = pstm_copy(&y, &t1)) != PSTM_OKAY) {
1432 if ((res = pstm_lshd (&t1, i - t - 1)) != PSTM_OKAY) {
1435 if ((res = pstm_add (&x, &t1, &x)) != PSTM_OKAY) {
1438 q.dp[i - t - 1] = q.dp[i - t - 1] - 1;
1442 now q is the quotient and x is the remainder (which we have to normalize)
1444 /* get sign before writing to c */
1445 x.sign = x.used == 0 ? PSTM_ZPOS : a->sign;
1449 if (pstm_copy (&q, c) != PSTM_OKAY) {
1457 if ((res = pstm_div_2d (pool, &x, norm, &x, NULL)) != PSTM_OKAY) {
1461 the following is a kludge, essentially we were seeing the right
1462 remainder but with excess digits that should have been zero
1464 for (i = b->used; i < x.used; i++) {
1468 if (pstm_copy (&x, d) != PSTM_OKAY) {
1476 LBL_Q:pstm_clear (&q);
1477 LBL_Y:pstm_clear (&y);
1478 LBL_X:pstm_clear (&x);
1479 LBL_T2:pstm_clear (&t2);
1480 LBL_T1:pstm_clear (&t1);
1485 /******************************************************************************/
1487 Swap the elements of two integers, for cases where you can't simply swap
1488 the pstm_int pointers around
1490 void pstm_exch(pstm_int * a, pstm_int * b)
1499 /******************************************************************************/
1501 c = a mod b, 0 <= c < b
1503 int32 pstm_mod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c)
1510 if ((err = pstm_init_size(pool, &t, b->alloc)) != PSTM_OKAY) {
1513 if ((err = pstm_div(pool, a, b, NULL, &t)) != PSTM_OKAY) {
1517 if (t.sign != b->sign) {
1518 err = pstm_add(&t, b, c);
1526 /******************************************************************************/
1530 int32 pstm_mulmod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c,
1534 int size; //bbox: was int16
1538 Smart-size pstm_inits. d is an output that is influenced by this local 't'
1539 so don't shrink 'd' if it wants to becuase this will lead to an pstm_grow
1542 size = a->used + b->used + 1;
1543 if ((a == d) && (size < a->alloc)) {
1546 if ((res = pstm_init_size(pool, &tmp, size)) != PSTM_OKAY) {
1549 if ((res = pstm_mul_comba(pool, a, b, &tmp, NULL, 0)) != PSTM_OKAY) {
1553 res = pstm_mod(pool, &tmp, c, d);
1558 /******************************************************************************/
1561 * Some restrictions... x must be positive and < b
1563 int32 pstm_exptmod(psPool_t *pool, pstm_int *G, pstm_int *X, pstm_int *P,
1566 pstm_int M[32], res; /* Keep this winsize based: (1 << max_winsize) */
1570 int bitcpy, bitcnt, mode, digidx, x, y, winsize; //bbox: was int16
1573 /* set window size from what user set as optimization */
1574 x = pstm_count_bits(X);
1578 winsize = PS_EXPTMOD_WINSIZE;
1581 /* now setup montgomery */
1582 if ((err = pstm_montgomery_setup (P, &mp)) != PSTM_OKAY) {
1587 if ((err = pstm_init_size(pool, &res, (P->used * 2) + 1)) != PSTM_OKAY) {
1592 The M table contains powers of the input base, e.g. M[x] = G^x mod P
1593 The first half of the table is not computed though except for M[0] and M[1]
1595 /* now we need R mod m */
1596 if ((err = pstm_montgomery_calc_normalization (&res, P)) != PSTM_OKAY) {
1603 if ((err = pstm_init_size(pool, &M[1], res.used)) != PSTM_OKAY) {
1607 /* now set M[1] to G * R mod m */
1608 if (pstm_cmp_mag(P, G) != PSTM_GT) {
1609 /* G > P so we reduce it first */
1610 if ((err = pstm_mod(pool, G, P, &M[1])) != PSTM_OKAY) {
1614 if ((err = pstm_copy(G, &M[1])) != PSTM_OKAY) {
1618 if ((err = pstm_mulmod (pool, &M[1], &res, P, &M[1])) != PSTM_OKAY) {
1622 Pre-allocated digit. Used for mul, sqr, AND reduce
1624 paDlen = ((M[1].used + 3) * 2) * sizeof(pstm_digit);
1625 paD = xzalloc(paDlen);//bbox
1627 compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times
1629 if (pstm_init_copy(pool, &M[1 << (winsize - 1)], &M[1], 1) != PSTM_OKAY) {
1633 for (x = 0; x < (winsize - 1); x++) {
1634 if ((err = pstm_sqr_comba (pool, &M[1 << (winsize - 1)],
1635 &M[1 << (winsize - 1)], paD, paDlen)) != PSTM_OKAY) {
1638 if ((err = pstm_montgomery_reduce(pool, &M[1 << (winsize - 1)], P, mp,
1639 paD, paDlen)) != PSTM_OKAY) {
1644 now init the second half of the array
1646 for (x = (1<<(winsize-1)) + 1; x < (1 << winsize); x++) {
1647 if ((err = pstm_init_size(pool, &M[x], M[1<<(winsize-1)].alloc + 1))
1649 for (y = 1<<(winsize-1); y < x; y++) {
1656 /* create upper table */
1657 for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
1658 if ((err = pstm_mul_comba(pool, &M[x - 1], &M[1], &M[x], paD, paDlen))
1662 if ((err = pstm_montgomery_reduce(pool, &M[x], P, mp, paD, paDlen)) !=
1668 /* set initial mode and bit cnt */
1672 digidx = X->used - 1;
1677 /* grab next digit as required */
1678 if (--bitcnt == 0) {
1679 /* if digidx == -1 we are out of digits so break */
1683 /* read next digit and reset bitcnt */
1684 buf = X->dp[digidx--];
1685 bitcnt = (int32)DIGIT_BIT;
1688 /* grab the next msb from the exponent */
1689 y = (pstm_digit)(buf >> (DIGIT_BIT - 1)) & 1;
1690 buf <<= (pstm_digit)1;
1692 If the bit is zero and mode == 0 then we ignore it.
1693 These represent the leading zero bits before the first 1 bit
1694 in the exponent. Technically this opt is not required but it
1695 does lower the # of trivial squaring/reductions used
1697 if (mode == 0 && y == 0) {
1701 /* if the bit is zero and mode == 1 then we square */
1702 if (mode == 1 && y == 0) {
1703 if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
1707 if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
1714 /* else we add it to the window */
1715 bitbuf |= (y << (winsize - ++bitcpy));
1718 if (bitcpy == winsize) {
1719 /* ok window is filled so square as required and mul square first */
1720 for (x = 0; x < winsize; x++) {
1721 if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
1725 if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD,
1726 paDlen)) != PSTM_OKAY) {
1732 if ((err = pstm_mul_comba(pool, &res, &M[bitbuf], &res, paD,
1733 paDlen)) != PSTM_OKAY) {
1736 if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
1741 /* empty window and reset */
1748 /* if bits remain then square/multiply */
1749 if (mode == 2 && bitcpy > 0) {
1750 /* square then multiply if the bit is set */
1751 for (x = 0; x < bitcpy; x++) {
1752 if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
1756 if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
1761 /* get next bit of the window */
1763 if ((bitbuf & (1 << winsize)) != 0) {
1765 if ((err = pstm_mul_comba(pool, &res, &M[1], &res, paD, paDlen))
1769 if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD,
1770 paDlen)) != PSTM_OKAY) {
1777 Fix up result if Montgomery reduction is used recall that any value in a
1778 Montgomery system is actually multiplied by R mod n. So we have to reduce
1779 one more time to cancel out the factor of R.
1781 if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen)) !=
1785 /* swap res with Y */
1786 if ((err = pstm_copy (&res, Y)) != PSTM_OKAY) {
1791 for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
1794 LBL_PAD:psFree(paD, pool);
1795 LBL_M: pstm_clear(&M[1]);
1796 LBL_RES:pstm_clear(&res);
1800 /******************************************************************************/
1804 int32 pstm_add(pstm_int *a, pstm_int *b, pstm_int *c)
1807 int sa, sb; //bbox: was int16
1809 /* get sign of both inputs */
1813 /* handle two cases, not four */
1815 /* both positive or both negative, add their mags, copy the sign */
1817 if ((res = s_pstm_add (a, b, c)) != PSTM_OKAY) {
1822 one positive, the other negative
1823 subtract the one with the greater magnitude from the one of the lesser
1824 magnitude. The result gets the sign of the one with the greater mag.
1826 if (pstm_cmp_mag (a, b) == PSTM_LT) {
1828 if ((res = s_pstm_sub (b, a, c)) != PSTM_OKAY) {
1833 if ((res = s_pstm_sub (a, b, c)) != PSTM_OKAY) {
1841 /******************************************************************************/
1843 reverse an array, used for radix code
1845 static void pstm_reverse (unsigned char *s, int len) //bbox: was int16 len
1860 /******************************************************************************/
1862 No reverse. Useful in some of the EIP-154 PKA stuff where special byte
1863 order seems to come into play more often
1865 int32 pstm_to_unsigned_bin_nr(psPool_t *pool, pstm_int *a, unsigned char *b)
1868 int x; //bbox: was int16
1871 if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) {
1876 while (pstm_iszero (&t) == 0) {
1877 b[x++] = (unsigned char) (t.dp[0] & 255);
1878 if ((res = pstm_div_2d (pool, &t, 8, &t, NULL)) != PSTM_OKAY) {
1886 /******************************************************************************/
1890 int32 pstm_to_unsigned_bin(psPool_t *pool, pstm_int *a, unsigned char *b)
1893 int x; //bbox: was int16
1896 if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) {
1901 while (pstm_iszero (&t) == 0) {
1902 b[x++] = (unsigned char) (t.dp[0] & 255);
1903 if ((res = pstm_div_2d (pool, &t, 8, &t, NULL)) != PSTM_OKAY) {
1908 pstm_reverse (b, x);
1913 /******************************************************************************/
1915 compare against a single digit
1917 int32 pstm_cmp_d(pstm_int *a, pstm_digit b)
1919 /* compare based on sign */
1920 if ((b && a->used == 0) || a->sign == PSTM_NEG) {
1924 /* compare based on magnitude */
1929 /* compare the only digit of a to b */
1932 } else if (a->dp[0] < b) {
1940 Need invmod for ECC and also private key loading for hardware crypto
1941 in cases where dQ > dP. The values must be switched and a new qP must be
1942 calculated using this function
1945 #define pstm_invmod_slow(pool, a, b, c) \
1946 pstm_invmod_slow( a, b, c)
1947 static int32 pstm_invmod_slow(psPool_t *pool, pstm_int * a, pstm_int * b,
1950 pstm_int x, y, u, v, A, B, C, D;
1953 /* b cannot be negative */
1954 if (b->sign == PSTM_NEG || pstm_iszero(b) == 1) {
1955 return PS_LIMIT_FAIL;
1959 if (pstm_init_size(pool, &x, b->used) != PSTM_OKAY) {
1964 if ((res = pstm_mod(pool, a, b, &x)) != PSTM_OKAY) {
1968 if (pstm_init_copy(pool, &y, b, 0) != PSTM_OKAY) {
1972 /* 2. [modified] if x,y are both even then return an error! */
1973 if (pstm_iseven (&x) == 1 && pstm_iseven (&y) == 1) {
1978 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
1979 if ((res = pstm_init_copy(pool, &u, &x, 0)) != PSTM_OKAY) {
1982 if ((res = pstm_init_copy(pool, &v, &y, 0)) != PSTM_OKAY) {
1986 if ((res = pstm_init_size(pool, &A, sizeof(pstm_digit))) != PSTM_OKAY) {
1990 if ((res = pstm_init_size(pool, &D, sizeof(pstm_digit))) != PSTM_OKAY) {
1996 if ((res = pstm_init(pool, &B)) != PSTM_OKAY) {
1999 if ((res = pstm_init(pool, &C)) != PSTM_OKAY) {
2004 /* 4. while u is even do */
2005 while (pstm_iseven (&u) == 1) {
2007 if ((res = pstm_div_2 (&u, &u)) != PSTM_OKAY) {
2011 /* 4.2 if A or B is odd then */
2012 if (pstm_isodd (&A) == 1 || pstm_isodd (&B) == 1) {
2013 /* A = (A+y)/2, B = (B-x)/2 */
2014 if ((res = pstm_add (&A, &y, &A)) != PSTM_OKAY) {
2017 if ((res = pstm_sub (&B, &x, &B)) != PSTM_OKAY) {
2021 /* A = A/2, B = B/2 */
2022 if ((res = pstm_div_2 (&A, &A)) != PSTM_OKAY) {
2025 if ((res = pstm_div_2 (&B, &B)) != PSTM_OKAY) {
2030 /* 5. while v is even do */
2031 while (pstm_iseven (&v) == 1) {
2033 if ((res = pstm_div_2 (&v, &v)) != PSTM_OKAY) {
2037 /* 5.2 if C or D is odd then */
2038 if (pstm_isodd (&C) == 1 || pstm_isodd (&D) == 1) {
2039 /* C = (C+y)/2, D = (D-x)/2 */
2040 if ((res = pstm_add (&C, &y, &C)) != PSTM_OKAY) {
2043 if ((res = pstm_sub (&D, &x, &D)) != PSTM_OKAY) {
2047 /* C = C/2, D = D/2 */
2048 if ((res = pstm_div_2 (&C, &C)) != PSTM_OKAY) {
2051 if ((res = pstm_div_2 (&D, &D)) != PSTM_OKAY) {
2056 /* 6. if u >= v then */
2057 if (pstm_cmp (&u, &v) != PSTM_LT) {
2058 /* u = u - v, A = A - C, B = B - D */
2059 if ((res = pstm_sub (&u, &v, &u)) != PSTM_OKAY) {
2062 if ((res = pstm_sub (&A, &C, &A)) != PSTM_OKAY) {
2065 if ((res = pstm_sub (&B, &D, &B)) != PSTM_OKAY) {
2069 /* v - v - u, C = C - A, D = D - B */
2070 if ((res = pstm_sub (&v, &u, &v)) != PSTM_OKAY) {
2073 if ((res = pstm_sub (&C, &A, &C)) != PSTM_OKAY) {
2076 if ((res = pstm_sub (&D, &B, &D)) != PSTM_OKAY) {
2081 /* if not zero goto step 4 */
2082 if (pstm_iszero (&u) == 0)
2085 /* now a = C, b = D, gcd == g*v */
2087 /* if v != 1 then there is no inverse */
2088 if (pstm_cmp_d (&v, 1) != PSTM_EQ) {
2093 /* if its too low */
2094 while (pstm_cmp_d(&C, 0) == PSTM_LT) {
2095 if ((res = pstm_add(&C, b, &C)) != PSTM_OKAY) {
2101 while (pstm_cmp_mag(&C, b) != PSTM_LT) {
2102 if ((res = pstm_sub(&C, b, &C)) != PSTM_OKAY) {
2107 /* C is now the inverse */
2108 if ((res = pstm_copy(&C, c)) != PSTM_OKAY) {
2113 LBL_C: pstm_clear(&C);
2114 LBL_D: pstm_clear(&D);
2115 LBL_B: pstm_clear(&B);
2116 LBL_A: pstm_clear(&A);
2117 LBL_V: pstm_clear(&v);
2118 LBL_U: pstm_clear(&u);
2119 LBL_Y: pstm_clear(&y);
2120 LBL_X: pstm_clear(&x);
2125 /* c = 1/a (mod b) for odd b only */
2126 int32 pstm_invmod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c)
2128 pstm_int x, y, u, v, B, D;
2130 int neg, sanity; //bbox: was uint16
2132 /* 2. [modified] b must be odd */
2133 if (pstm_iseven (b) == 1) {
2134 return pstm_invmod_slow(pool, a,b,c);
2137 /* x == modulus, y == value to invert */
2138 if ((res = pstm_init_copy(pool, &x, b, 0)) != PSTM_OKAY) {
2142 if ((res = pstm_init_size(pool, &y, a->alloc)) != PSTM_OKAY) {
2146 /* we need y = |a| */
2149 /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
2150 if ((res = pstm_init_copy(pool, &u, &x, 0)) != PSTM_OKAY) {
2153 if ((res = pstm_init_copy(pool, &v, &y, 0)) != PSTM_OKAY) {
2156 if ((res = pstm_init(pool, &B)) != PSTM_OKAY) {
2159 if ((res = pstm_init(pool, &D)) != PSTM_OKAY) {
2167 /* 4. while u is even do */
2168 while (pstm_iseven (&u) == 1) {
2170 if ((res = pstm_div_2 (&u, &u)) != PSTM_OKAY) {
2174 /* 4.2 if B is odd then */
2175 if (pstm_isodd (&B) == 1) {
2176 if ((res = pstm_sub (&B, &x, &B)) != PSTM_OKAY) {
2181 if ((res = pstm_div_2 (&B, &B)) != PSTM_OKAY) {
2186 /* 5. while v is even do */
2187 while (pstm_iseven (&v) == 1) {
2189 if ((res = pstm_div_2 (&v, &v)) != PSTM_OKAY) {
2192 /* 5.2 if D is odd then */
2193 if (pstm_isodd (&D) == 1) {
2195 if ((res = pstm_sub (&D, &x, &D)) != PSTM_OKAY) {
2200 if ((res = pstm_div_2 (&D, &D)) != PSTM_OKAY) {
2205 /* 6. if u >= v then */
2206 if (pstm_cmp (&u, &v) != PSTM_LT) {
2207 /* u = u - v, B = B - D */
2208 if ((res = pstm_sub (&u, &v, &u)) != PSTM_OKAY) {
2211 if ((res = pstm_sub (&B, &D, &B)) != PSTM_OKAY) {
2215 /* v - v - u, D = D - B */
2216 if ((res = pstm_sub (&v, &u, &v)) != PSTM_OKAY) {
2219 if ((res = pstm_sub (&D, &B, &D)) != PSTM_OKAY) {
2224 /* if not zero goto step 4 */
2225 if (sanity++ > 1000) {
2226 res = PS_LIMIT_FAIL;
2229 if (pstm_iszero (&u) == 0) {
2233 /* now a = C, b = D, gcd == g*v */
2235 /* if v != 1 then there is no inverse */
2236 if (pstm_cmp_d (&v, 1) != PSTM_EQ) {
2241 /* b is now the inverse */
2243 while (D.sign == PSTM_NEG) {
2244 if ((res = pstm_add (&D, b, &D)) != PSTM_OKAY) {
2248 if ((res = pstm_copy (&D, c)) != PSTM_OKAY) {
2254 LBL_D: pstm_clear(&D);
2255 LBL_B: pstm_clear(&B);
2256 LBL_V: pstm_clear(&v);
2257 LBL_U: pstm_clear(&u);
2258 LBL_Y: pstm_clear(&y);
2259 LBL_X: pstm_clear(&x);
2262 #endif /* !DISABLE_PSTM */
2263 /******************************************************************************/