home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / calc / part16 < prev    next >
Encoding:
Text File  |  1992-05-09  |  34.6 KB  |  1,386 lines

  1. Newsgroups: comp.sources.unix
  2. From: dbell@pdact.pd.necisa.oz.au (David I. Bell)
  3. Subject: v26i042: CALC - An arbitrary precision C-like calculator, Part16/21
  4. Sender: unix-sources-moderator@pa.dec.com
  5. Approved: vixie@pa.dec.com
  6.  
  7. Submitted-By: dbell@pdact.pd.necisa.oz.au (David I. Bell)
  8. Posting-Number: Volume 26, Issue 42
  9. Archive-Name: calc/part16
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 16 (of 21)."
  18. # Contents:  zmod.c
  19. # Wrapped by dbell@elm on Tue Feb 25 15:21:14 1992
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'zmod.c' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'zmod.c'\"
  23. else
  24. echo shar: Extracting \"'zmod.c'\" \(32468 characters\)
  25. sed "s/^X//" >'zmod.c' <<'END_OF_FILE'
  26. X/*
  27. X * Copyright (c) 1992 David I. Bell
  28. X * Permission is granted to use, distribute, or modify this source,
  29. X * provided that this copyright notice remains intact.
  30. X *
  31. X * Routines to do modulo arithmetic both normally and also using the REDC
  32. X * algorithm given by Peter L. Montgomery in Mathematics of Computation,
  33. X * volume 44, number 170 (April, 1985).  For multiple multiplies using
  34. X * the same large modulus, the REDC algorithm avoids the usual division
  35. X * by the modulus, instead replacing it with two multiplies or else a
  36. X * special algorithm.  When these two multiplies or the special algorithm
  37. X * are faster then the division, then the REDC algorithm is better.
  38. X */
  39. X
  40. X#include "math.h"
  41. X
  42. X
  43. X#define    POWBITS    4        /* bits for power chunks (must divide BASEB) */
  44. X#define    POWNUMS    (1<<POWBITS)    /* number of powers needed in table */
  45. X
  46. X
  47. XLEN _pow2_ = POW_ALG2;        /* modulo size to use REDC for powers */
  48. XLEN _redc2_ = REDC_ALG2;    /* modulo size to use second REDC algorithm */
  49. X
  50. Xstatic REDC *powermodredc = NULL;    /* REDC info for raising to power */
  51. X
  52. X#if 0
  53. Xextern void zaddmod proto((ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res));
  54. Xextern void znegmod proto((ZVALUE z1, ZVALUE z2, ZVALUE *res));
  55. X
  56. X/*
  57. X * Multiply two numbers together and then mod the result with a third number.
  58. X * The two numbers to be multiplied can be negative or out of modulo range.
  59. X * The result will be in the range 0 to the modulus - 1.
  60. X */
  61. Xvoid
  62. Xzmulmod(z1, z2, z3, res)
  63. X    ZVALUE z1;        /* first number to be multiplied */
  64. X    ZVALUE z2;        /* second number to be multiplied */
  65. X    ZVALUE z3;        /* number to take mod with */
  66. X    ZVALUE *res;        /* result */
  67. X{
  68. X    ZVALUE tmp;
  69. X    FULL prod;
  70. X    FULL digit;
  71. X    BOOL neg;
  72. X
  73. X    if (iszero(z3) || isneg(z3))
  74. X        error("Mod of non-positive integer");
  75. X    if (iszero(z1) || iszero(z2) || isunit(z3)) {
  76. X        *res = _zero_;
  77. X        return;
  78. X    }
  79. X
  80. X    /*
  81. X     * If the modulus is a single digit number, then do the result
  82. X     * cheaply.  Check especially for a small power of two.
  83. X     */
  84. X    if (istiny(z3)) {
  85. X        neg = (z1.sign != z2.sign);
  86. X        digit = z3.v[0];
  87. X        if ((digit & -digit) == digit) {    /* NEEDS 2'S COMP */
  88. X            prod = ((FULL) z1.v[0]) * ((FULL) z2.v[0]);
  89. X            prod &= (digit - 1);
  90. X        } else {
  91. X            z1.sign = 0;
  92. X            z2.sign = 0;
  93. X            prod = (FULL) zmodi(z1, (long) digit);
  94. X            prod *= (FULL) zmodi(z2, (long) digit);
  95. X            prod %= digit;
  96. X        }
  97. X        if (neg && prod)
  98. X            prod = digit - prod;
  99. X        itoz((long) prod, res);
  100. X        return;
  101. X    }
  102. X
  103. X    /*
  104. X     * The modulus is more than one digit.
  105. X     * Actually do the multiply and divide if necessary.
  106. X     */
  107. X    zmul(z1, z2, &tmp);
  108. X    if (ispos(tmp) && ((tmp.len < z3.len) || ((tmp.len == z3.len) &&
  109. X        (tmp.v[tmp.len-1] < z2.v[z3.len-1]))))
  110. X    {
  111. X        *res = tmp;
  112. X        return;
  113. X    }
  114. X    zmod(tmp, z3, res);
  115. X    freeh(tmp.v);
  116. X}
  117. X
  118. X
  119. X/*
  120. X * Square a number and then mod the result with a second number.
  121. X * The number to be squared can be negative or out of modulo range.
  122. X * The result will be in the range 0 to the modulus - 1.
  123. X */
  124. Xvoid
  125. Xzsquaremod(z1, z2, res)
  126. X    ZVALUE z1;        /* number to be squared */
  127. X    ZVALUE z2;        /* number to take mod with */
  128. X    ZVALUE *res;        /* result */
  129. X{
  130. X    ZVALUE tmp;
  131. X    FULL prod;
  132. X    FULL digit;
  133. X
  134. X    if (iszero(z2) || isneg(z2))
  135. X        error("Mod of non-positive integer");
  136. X    if (iszero(z1) || isunit(z2)) {
  137. X        *res = _zero_;
  138. X        return;
  139. X    }
  140. X
  141. X    /*
  142. X     * If the modulus is a single digit number, then do the result
  143. X     * cheaply.  Check especially for a small power of two.
  144. X     */
  145. X    if (istiny(z2)) {
  146. X        digit = z2.v[0];
  147. X        if ((digit & -digit) == digit) {    /* NEEDS 2'S COMP */
  148. X            prod = (FULL) z1.v[0];
  149. X            prod = (prod * prod) & (digit - 1);
  150. X        } else {
  151. X            z1.sign = 0;
  152. X            prod = (FULL) zmodi(z1, (long) digit);
  153. X            prod = (prod * prod) % digit;
  154. X        }
  155. X        itoz((long) prod, res);
  156. X        return;
  157. X    }
  158. X
  159. X    /*
  160. X     * The modulus is more than one digit.
  161. X     * Actually do the square and divide if necessary.
  162. X     */
  163. X    zsquare(z1, &tmp);
  164. X    if ((tmp.len < z2.len) ||
  165. X        ((tmp.len == z2.len) && (tmp.v[tmp.len-1] < z2.v[z2.len-1]))) {
  166. X            *res = tmp;
  167. X            return;
  168. X    }
  169. X    zmod(tmp, z2, res);
  170. X    freeh(tmp.v);
  171. X}
  172. X
  173. X
  174. X/*
  175. X * Add two numbers together and then mod the result with a third number.
  176. X * The two numbers to be added can be negative or out of modulo range.
  177. X * The result will be in the range 0 to the modulus - 1.
  178. X */
  179. Xstatic void
  180. Xzaddmod(z1, z2, z3, res)
  181. X    ZVALUE z1;        /* first number to be added */
  182. X    ZVALUE z2;        /* second number to be added */
  183. X    ZVALUE z3;        /* number to take mod with */
  184. X    ZVALUE *res;        /* result */
  185. X{
  186. X    ZVALUE tmp;
  187. X    FULL sumdigit;
  188. X    FULL moddigit;
  189. X
  190. X    if (iszero(z3) || isneg(z3))
  191. X        error("Mod of non-positive integer");
  192. X    if ((iszero(z1) && iszero(z2)) || isunit(z3)) {
  193. X        *res = _zero_;
  194. X        return;
  195. X    }
  196. X    if (istwo(z2)) {
  197. X        if ((z1.v[0] + z2.v[0]) & 0x1)
  198. X            *res = _one_;
  199. X        else
  200. X            *res = _zero_;
  201. X        return;
  202. X    }
  203. X    zadd(z1, z2, &tmp);
  204. X    if (isneg(tmp) || (tmp.len > z3.len)) {
  205. X        zmod(tmp, z3, res);
  206. X        freeh(tmp.v);
  207. X        return;
  208. X    }
  209. X    sumdigit = tmp.v[tmp.len - 1];
  210. X    moddigit = z3.v[z3.len - 1];
  211. X    if ((tmp.len < z3.len) || (sumdigit < moddigit)) {
  212. X        *res = tmp;
  213. X        return;
  214. X    }
  215. X    if (sumdigit < 2 * moddigit) {
  216. X        zsub(tmp, z3, res);
  217. X        freeh(tmp.v);
  218. X        return;
  219. X    }
  220. X    zmod(tmp, z2, res);
  221. X    freeh(tmp.v);
  222. X}
  223. X
  224. X
  225. X/*
  226. X * Subtract two numbers together and then mod the result with a third number.
  227. X * The two numbers to be subtract can be negative or out of modulo range.
  228. X * The result will be in the range 0 to the modulus - 1.
  229. X */
  230. Xvoid
  231. Xzsubmod(z1, z2, z3, res)
  232. X    ZVALUE z1;        /* number to be subtracted from */
  233. X    ZVALUE z2;        /* number to be subtracted */
  234. X    ZVALUE z3;        /* number to take mod with */
  235. X    ZVALUE *res;        /* result */
  236. X{
  237. X    if (iszero(z3) || isneg(z3))
  238. X        error("Mod of non-positive integer");
  239. X    if (iszero(z2)) {
  240. X        zmod(z1, z3, res);
  241. X        return;
  242. X    }
  243. X    if (iszero(z1)) {
  244. X        znegmod(z2, z3, res);
  245. X        return;
  246. X    }
  247. X    if ((z1.sign == z2.sign) && (z1.len == z2.len) &&
  248. X        (z1.v[0] == z2.v[0]) && (zcmp(z1, z2) == 0)) {
  249. X            *res = _zero_;
  250. X            return;
  251. X    }
  252. X    z2.sign = !z2.sign;
  253. X    zaddmod(z1, z2, z3, res);
  254. X}
  255. X
  256. X
  257. X/*
  258. X * Calculate the negative of a number modulo another number.
  259. X * The number to be negated can be negative or out of modulo range.
  260. X * The result will be in the range 0 to the modulus - 1.
  261. X */
  262. Xstatic void
  263. Xznegmod(z1, z2, res)
  264. X    ZVALUE z1;        /* number to take negative of */
  265. X    ZVALUE z2;        /* number to take mod with */
  266. X    ZVALUE *res;        /* result */
  267. X{
  268. X    int sign;
  269. X    int cv;
  270. X
  271. X    if (iszero(z2) || isneg(z2))
  272. X        error("Mod of non-positive integer");
  273. X    if (iszero(z1) || isunit(z2)) {
  274. X        *res = _zero_;
  275. X        return;
  276. X    }
  277. X    if (istwo(z2)) {
  278. X        if (z1.v[0] & 0x1)
  279. X            *res = _one_;
  280. X        else
  281. X            *res = _zero_;
  282. X        return;
  283. X    }
  284. X
  285. X    /*
  286. X     * If the absolute value of the number is within the modulo range,
  287. X     * then the result is just a copy or a subtraction.  Otherwise go
  288. X     * ahead and negate and reduce the result.
  289. X     */
  290. X    sign = z1.sign;
  291. X    z1.sign = 0;
  292. X    cv = zrel(z1, z2);
  293. X    if (cv == 0) {
  294. X        *res = _zero_;
  295. X        return;
  296. X    }
  297. X    if (cv < 0) {
  298. X        if (sign)
  299. X            zcopy(z1, res);
  300. X        else
  301. X            zsub(z2, z1, res);
  302. X        return;
  303. X    }
  304. X    z1.sign = !sign;
  305. X    zmod(z1, z2, res);
  306. X}
  307. X#endif
  308. X
  309. X
  310. X/*
  311. X * Calculate the number congruent to the given number whose absolute
  312. X * value is minimal.  The number to be reduced can be negative or out of
  313. X * modulo range.  The result will be within the range -int((modulus-1)/2)
  314. X * to int(modulus/2) inclusive.  For example, for modulus 7, numbers are
  315. X * reduced to the range [-3, 3], and for modulus 8, numbers are reduced to
  316. X * the range [-3, 4].
  317. X */
  318. Xvoid
  319. Xzminmod(z1, z2, res)
  320. X    ZVALUE z1;        /* number to find minimum congruence of */
  321. X    ZVALUE z2;        /* number to take mod with */
  322. X    ZVALUE *res;        /* result */
  323. X{
  324. X    ZVALUE tmp1, tmp2;
  325. X    int sign;
  326. X    int cv;
  327. X
  328. X    if (iszero(z2) || isneg(z2))
  329. X        error("Mod of non-positive integer");
  330. X    if (iszero(z1) || isunit(z2)) {
  331. X        *res = _zero_;
  332. X        return;
  333. X    }
  334. X    if (istwo(z2)) {
  335. X        if (isodd(z1))
  336. X            *res = _one_;
  337. X        else
  338. X            *res = _zero_;
  339. X        return;
  340. X    }
  341. X
  342. X    /*
  343. X     * Do a quick check to see if the number is very small compared
  344. X     * to the modulus.  If so, then the result is obvious.
  345. X     */
  346. X    if (z1.len < z2.len - 1) {
  347. X        zcopy(z1, res);
  348. X        return;
  349. X    }
  350. X
  351. X    /*
  352. X     * Now make sure the input number is within the modulo range.
  353. X     * If not, then reduce it to be within range and make the
  354. X     * quick check again.
  355. X     */
  356. X    sign = z1.sign;
  357. X    z1.sign = 0;
  358. X    cv = zrel(z1, z2);
  359. X    if (cv == 0) {
  360. X        *res = _zero_;
  361. X        return;
  362. X    }
  363. X    tmp1 = z1;
  364. X    if (cv > 0) {
  365. X        z1.sign = (BOOL)sign;
  366. X        zmod(z1, z2, &tmp1);
  367. X        if (tmp1.len < z2.len - 1) {
  368. X            *res = tmp1;
  369. X            return;
  370. X        }
  371. X        sign = 0;
  372. X    }
  373. X
  374. X    /*
  375. X     * Now calculate the difference of the modulus and the absolute
  376. X     * value of the original number.  Compare the original number with
  377. X     * the difference, and return the one with the smallest absolute
  378. X     * value, with the correct sign.  If the two values are equal, then
  379. X     * return the positive result.
  380. X     */
  381. X    zsub(z2, tmp1, &tmp2);
  382. X    cv = zrel(tmp1, tmp2);
  383. X    if (cv < 0) {
  384. X        freeh(tmp2.v);
  385. X        tmp1.sign = (BOOL)sign;
  386. X        if (tmp1.v == z1.v)
  387. X            zcopy(tmp1, res);
  388. X        else
  389. X            *res = tmp1;
  390. X    } else {
  391. X        if (cv)
  392. X            tmp2.sign = !sign;
  393. X        if (tmp1.v != z1.v)
  394. X            freeh(tmp1.v);
  395. X        *res = tmp2;
  396. X    }
  397. X}
  398. X
  399. X
  400. X/*
  401. X * Compare two numbers for equality modulo a third number.
  402. X * The two numbers to be compared can be negative or out of modulo range.
  403. X * Returns TRUE if the numbers are not congruent, and FALSE if they are
  404. X * congruent.
  405. X */
  406. XBOOL
  407. Xzcmpmod(z1, z2, z3)
  408. X    ZVALUE z1;        /* first number to be compared */
  409. X    ZVALUE z2;        /* second number to be compared */
  410. X    ZVALUE z3;        /* modulus */
  411. X{
  412. X    ZVALUE tmp1, tmp2, tmp3;
  413. X    FULL digit;
  414. X    LEN len;
  415. X    int cv;
  416. X
  417. X    if (isneg(z3) || iszero(z3))
  418. X        error("Non-positive modulus in zcmpmod");
  419. X    if (istwo(z3))
  420. X        return (((z1.v[0] + z2.v[0]) & 0x1) != 0);
  421. X
  422. X    /*
  423. X     * If the two numbers are equal, then their mods are equal.
  424. X     */
  425. X    if ((z1.sign == z2.sign) && (z1.len == z2.len) &&
  426. X        (z1.v[0] == z2.v[0]) && (zcmp(z1, z2) == 0))
  427. X            return FALSE;
  428. X
  429. X    /*
  430. X     * If both numbers are negative, then we can make them positive.
  431. X     */
  432. X    if (isneg(z1) && isneg(z2)) {
  433. X        z1.sign = 0;
  434. X        z2.sign = 0;
  435. X    }
  436. X
  437. X    /*
  438. X     * For small negative numbers, make them positive before comparing.
  439. X     * In any case, the resulting numbers are in tmp1 and tmp2.
  440. X     */
  441. X    tmp1 = z1;
  442. X    tmp2 = z2;
  443. X    len = z3.len;
  444. X    digit = z3.v[len - 1];
  445. X
  446. X    if (isneg(z1) && ((z1.len < len) ||
  447. X        ((z1.len == len) && (z1.v[z1.len - 1] < digit))))
  448. X            zadd(z1, z3, &tmp1);
  449. X
  450. X    if (isneg(z2) && ((z2.len < len) ||
  451. X        ((z2.len == len) && (z2.v[z2.len - 1] < digit))))
  452. X            zadd(z2, z3, &tmp2);
  453. X
  454. X    /*
  455. X     * Now compare the two numbers for equality.
  456. X     * If they are equal we are all done.
  457. X     */
  458. X    if (zcmp(tmp1, tmp2) == 0) {
  459. X        if (tmp1.v != z1.v)
  460. X            freeh(tmp1.v);
  461. X        if (tmp2.v != z2.v)
  462. X            freeh(tmp2.v);
  463. X        return FALSE;
  464. X    }
  465. X
  466. X    /*
  467. X     * They are not identical.  Now if both numbers are positive
  468. X     * and less than the modulus, then they are definitely not equal.
  469. X     */
  470. X    if ((tmp1.sign == tmp2.sign) &&
  471. X        ((tmp1.len < len) || (zrel(tmp1, z3) < 0)) &&
  472. X        ((tmp2.len < len) || (zrel(tmp2, z3) < 0)))
  473. X    {
  474. X        if (tmp1.v != z1.v)
  475. X            freeh(tmp1.v);
  476. X        if (tmp2.v != z2.v)
  477. X            freeh(tmp2.v);
  478. X        return TRUE;
  479. X    }
  480. X
  481. X    /*
  482. X     * Either one of the numbers is negative or is large.
  483. X     * So do the standard thing and subtract the two numbers.
  484. X     * Then they are equal if the result is 0 (mod z3).
  485. X     */
  486. X    zsub(tmp1, tmp2, &tmp3);
  487. X    if (tmp1.v != z1.v)
  488. X        freeh(tmp1.v);
  489. X    if (tmp2.v != z2.v)
  490. X        freeh(tmp2.v);
  491. X
  492. X    /*
  493. X     * Compare the result with the modulus to see if it is equal to
  494. X     * or less than the modulus.  If so, we know the mod result.
  495. X     */
  496. X    tmp3.sign = 0;
  497. X    cv = zrel(tmp3, z3);
  498. X    if (cv == 0) {
  499. X        freeh(tmp3.v);
  500. X        return FALSE;
  501. X    }
  502. X    if (cv < 0) {
  503. X        freeh(tmp3.v);
  504. X        return TRUE;
  505. X    }
  506. X
  507. X    /*
  508. X     * We are forced to actually do the division.
  509. X     * The numbers are congruent if the result is zero.
  510. X     */
  511. X    zmod(tmp3, z3, &tmp1);
  512. X    freeh(tmp3.v);
  513. X    if (iszero(tmp1)) {
  514. X        freeh(tmp1.v);
  515. X        return FALSE;
  516. X    } else {
  517. X        freeh(tmp1.v);
  518. X        return TRUE;
  519. X    }
  520. X}
  521. X
  522. X
  523. X/*
  524. X * Compute the result of raising one number to a power modulo another number.
  525. X * That is, this computes:  a^b (modulo c).
  526. X * This calculates the result by examining the power POWBITS bits at a time,
  527. X * using a small table of POWNUMS low powers to calculate powers for those bits,
  528. X * and repeated squaring and multiplying by the partial powers to generate
  529. X * the complete power.  If the power being raised to is high enough, then
  530. X * this uses the REDC algorithm to avoid doing many divisions.  When using
  531. X * REDC, multiple calls to this routine using the same modulus will be
  532. X * slightly faster.
  533. X */
  534. Xvoid
  535. Xzpowermod(z1, z2, z3, res)
  536. X    ZVALUE z1, z2, z3, *res;
  537. X{
  538. X    HALF *hp;        /* pointer to current word of the power */
  539. X    REDC *rp;        /* REDC information to be used */
  540. X    ZVALUE *pp;        /* pointer to low power table */
  541. X    ZVALUE ans, temp;    /* calculation values */
  542. X    ZVALUE modpow;        /* current small power */
  543. X    ZVALUE lowpowers[POWNUMS];    /* low powers */
  544. X    int sign;        /* original sign of number */
  545. X    int curshift;        /* shift value for word of power */
  546. X    HALF curhalf;        /* current word of power */
  547. X    unsigned int curpow;    /* current low power */
  548. X    unsigned int curbit;    /* current bit of low power */
  549. X    int i;
  550. X
  551. X    if (isneg(z3) || iszero(z3))
  552. X        error("Non-positive modulus in zpowermod");
  553. X    if (isneg(z2))
  554. X        error("Negative power in zpowermod");
  555. X
  556. X    sign = z1.sign;
  557. X    z1.sign = 0;
  558. X
  559. X    /*
  560. X     * Check easy cases first.
  561. X     */
  562. X    if (iszero(z1) || isunit(z3)) {        /* 0^x or mod 1 */
  563. X        *res = _zero_;
  564. X        return;
  565. X    }
  566. X    if (istwo(z3)) {            /* mod 2 */
  567. X        if (isodd(z1))
  568. X            *res = _one_;
  569. X        else
  570. X            *res = _zero_;
  571. X        return;
  572. X    }
  573. X    if (isunit(z1) && (!sign || iseven(z2))) {
  574. X        /* 1^x or (-1)^(2x) */
  575. X        *res = _one_;
  576. X        return;
  577. X    }
  578. X
  579. X    /*
  580. X     * Normalize the number being raised to be non-negative and to lie
  581. X     * within the modulo range.  Then check for zero or one specially.
  582. X     */
  583. X    zmod(z1, z3, &temp);
  584. X    if (iszero(temp)) {
  585. X        freeh(temp.v);
  586. X        *res = _zero_;
  587. X        return;
  588. X    }
  589. X    z1 = temp;
  590. X    if (sign) {
  591. X        zsub(z3, z1, &temp);
  592. X        freeh(z1.v);
  593. X        z1 = temp;
  594. X    }
  595. X    if (isunit(z1)) {
  596. X        freeh(z1.v);
  597. X        *res = _one_;
  598. X        return;
  599. X    }
  600. X
  601. X    /*
  602. X     * If the modulus is odd, large enough, is not one less than an
  603. X     * exact power of two, and if the power is large enough, then use
  604. X     * the REDC algorithm.  The size where this is done is configurable.
  605. X     */
  606. X    if ((z2.len > 1) && (z3.len >= _pow2_) && isodd(z3)
  607. X        && !zisallbits(z3))
  608. X    {
  609. X        if (powermodredc && zcmp(powermodredc->mod, z3)) {
  610. X            zredcfree(powermodredc);
  611. X            powermodredc = NULL;
  612. X        }
  613. X        if (powermodredc == NULL)
  614. X            powermodredc = zredcalloc(z3);
  615. X        rp = powermodredc;
  616. X        zredcencode(rp, z1, &temp);
  617. X        zredcpower(rp, temp, z2, &z1);
  618. X        freeh(temp.v);
  619. X        zredcdecode(rp, z1, res);
  620. X        freeh(z1.v);
  621. X        return;
  622. X    }
  623. X
  624. X    /*
  625. X     * Modulus or power is small enough to perform the power raising
  626. X     * directly.  Initialize the table of powers.
  627. X     */
  628. X    for (pp = &lowpowers[2]; pp < &lowpowers[POWNUMS]; pp++)
  629. X        pp->len = 0;
  630. X    lowpowers[0] = _one_;
  631. X    lowpowers[1] = z1;
  632. X    ans = _one_;
  633. X
  634. X    hp = &z2.v[z2.len - 1];
  635. X    curhalf = *hp;
  636. X    curshift = BASEB - POWBITS;
  637. X    while (curshift && ((curhalf >> curshift) == 0))
  638. X        curshift -= POWBITS;
  639. X
  640. X    /*
  641. X     * Calculate the result by examining the power POWBITS bits at a time,
  642. X     * and use the table of low powers at each iteration.
  643. X     */
  644. X    for (;;) {
  645. X        curpow = (curhalf >> curshift) & (POWNUMS - 1);
  646. X        pp = &lowpowers[curpow];
  647. X
  648. X        /*
  649. X         * If the small power is not yet saved in the table, then
  650. X         * calculate it and remember it in the table for future use.
  651. X         */
  652. X        if (pp->len == 0) {
  653. X            if (curpow & 0x1)
  654. X                zcopy(z1, &modpow);
  655. X            else
  656. X                modpow = _one_;
  657. X
  658. X            for (curbit = 0x2; curbit <= curpow; curbit *= 2) {
  659. X                pp = &lowpowers[curbit];
  660. X                if (pp->len == 0) {
  661. X                    zsquare(lowpowers[curbit/2], &temp);
  662. X                    zmod(temp, z3, pp);
  663. X                    freeh(temp.v);
  664. X                }
  665. X                if (curbit & curpow) {
  666. X                    zmul(*pp, modpow, &temp);
  667. X                    freeh(modpow.v);
  668. X                    zmod(temp, z3, &modpow);
  669. X                    freeh(temp.v);
  670. X                }
  671. X            }
  672. X            pp = &lowpowers[curpow];
  673. X            *pp = modpow;
  674. X        }
  675. X
  676. X        /*
  677. X         * If the power is nonzero, then accumulate the small power
  678. X         * into the result.
  679. X         */
  680. X        if (curpow) {
  681. X            zmul(ans, *pp, &temp);
  682. X            freeh(ans.v);
  683. X            zmod(temp, z3, &ans);
  684. X            freeh(temp.v);
  685. X        }
  686. X
  687. X        /*
  688. X         * Select the next POWBITS bits of the power, if there is
  689. X         * any more to generate.
  690. X         */
  691. X        curshift -= POWBITS;
  692. X        if (curshift < 0) {
  693. X            if (hp-- == z2.v)
  694. X                break;
  695. X            curhalf = *hp;
  696. X            curshift = BASEB - POWBITS;
  697. X        }
  698. X
  699. X        /*
  700. X         * Square the result POWBITS times to make room for the next
  701. X         * chunk of bits.
  702. X         */
  703. X        for (i = 0; i < POWBITS; i++) {
  704. X            zsquare(ans, &temp);
  705. X            freeh(ans.v);
  706. X            zmod(temp, z3, &ans);
  707. X            freeh(temp.v);
  708. X        }
  709. X    }
  710. X
  711. X    for (pp = &lowpowers[2]; pp < &lowpowers[POWNUMS]; pp++) {
  712. X        if (pp->len)
  713. X            freeh(pp->v);
  714. X    }
  715. X    *res = ans;
  716. X}
  717. X
  718. X
  719. X/*
  720. X * Initialize the REDC algorithm for a particular modulus,
  721. X * returning a pointer to a structure that is used for other
  722. X * REDC calls.  An error is generated if the structure cannot
  723. X * be allocated.  The modulus must be odd and positive.
  724. X */
  725. XREDC *
  726. Xzredcalloc(z1)
  727. X    ZVALUE z1;        /* modulus to initialize for */
  728. X{
  729. X    REDC *rp;        /* REDC information */
  730. X    ZVALUE tmp;
  731. X    long bit;
  732. X
  733. X    if (iseven(z1) || isneg(z1))
  734. X        error("REDC requires positive odd modulus");
  735. X
  736. X    rp = (REDC *) malloc(sizeof(REDC));
  737. X    if (rp == NULL)
  738. X        error("Cannot allocate REDC structure");
  739. X
  740. X    /*
  741. X     * Round up the binary modulus to the next power of two
  742. X     * which is at a word boundary.  Then the shift and modulo
  743. X     * operations mod the binary modulus can be done very cheaply.
  744. X     * Calculate the REDC format for the number 1 for future use.
  745. X     */
  746. X    bit = zhighbit(z1) + 1;
  747. X    if (bit % BASEB)
  748. X        bit += (BASEB - (bit % BASEB));
  749. X    zcopy(z1, &rp->mod);
  750. X    zbitvalue(bit, &tmp);
  751. X    z1.sign = 1;
  752. X    (void) zmodinv(z1, tmp, &rp->inv);
  753. X    zmod(tmp, rp->mod, &rp->one);
  754. X    freeh(tmp.v);
  755. X    rp->len = bit / BASEB;
  756. X    return rp;
  757. X}
  758. X
  759. X
  760. X/*
  761. X * Free any numbers associated with the specified REDC structure,
  762. X * and then the REDC structure itself.
  763. X */
  764. Xvoid
  765. Xzredcfree(rp)
  766. X    REDC *rp;        /* REDC information to be cleared */
  767. X{
  768. X    freeh(rp->mod.v);
  769. X    freeh(rp->inv.v);
  770. X    freeh(rp->one.v);
  771. X    free(rp);
  772. X}
  773. X
  774. X
  775. X/*
  776. X * Convert a normal number into the specified REDC format.
  777. X * The number to be converted can be negative or out of modulo range.
  778. X * The resulting number can be used for multiplying, adding, subtracting,
  779. X * or comparing with any other such converted numbers, as if the numbers
  780. X * were being calculated modulo the number which initialized the REDC
  781. X * information.  When the final value is unconverted, the result is the
  782. X * same as if the usual operations were done with the original numbers.
  783. X */
  784. Xvoid
  785. Xzredcencode(rp, z1, res)
  786. X    REDC *rp;        /* REDC information */
  787. X    ZVALUE z1;        /* number to be converted */
  788. X    ZVALUE *res;        /* returned converted number */
  789. X{
  790. X    ZVALUE tmp1, tmp2;
  791. X
  792. X    /*
  793. X     * Handle the cases 0, 1, -1, and 2 specially since these are
  794. X     * easy to calculate.  Zero transforms to zero, and the others
  795. X     * can be obtained from the precomputed REDC format for 1 since
  796. X     * addition and subtraction act normally for REDC format numbers.
  797. X     */
  798. X    if (iszero(z1)) {
  799. X        *res = _zero_;
  800. X        return;
  801. X    }
  802. X    if (isone(z1)) {
  803. X        zcopy(rp->one, res);
  804. X        return;
  805. X    }
  806. X    if (isunit(z1)) {
  807. X        zsub(rp->mod, rp->one, res);
  808. X        return;
  809. X    }
  810. X    if (istwo(z1)) {
  811. X        zadd(rp->one, rp->one, &tmp1);
  812. X        if (zrel(tmp1, rp->mod) < 0) {
  813. X            *res = tmp1;
  814. X            return;
  815. X        }
  816. X        zsub(tmp1, rp->mod, res);
  817. X        freeh(tmp1.v);
  818. X        return;
  819. X    }
  820. X
  821. X    /*
  822. X     * Not a trivial number to convert, so do the full transformation.
  823. X     * Convert negative numbers to positive numbers before converting.
  824. X     */
  825. X    tmp1.len = 0;
  826. X    if (isneg(z1)) {
  827. X        zmod(z1, rp->mod, &tmp1);
  828. X        z1 = tmp1;
  829. X    }
  830. X    zshift(z1, rp->len * BASEB, &tmp2);
  831. X    if (tmp1.len)
  832. X        freeh(tmp1.v);
  833. X    zmod(tmp2, rp->mod, res);
  834. X    freeh(tmp2.v);
  835. X}
  836. X
  837. X
  838. X/*
  839. X * The REDC algorithm used to convert numbers out of REDC format and also
  840. X * used after multiplication of two REDC numbers.  Using this routine
  841. X * avoids any divides, replacing the divide by two multiplications.
  842. X * If the numbers are very large, then these two multiplies will be
  843. X * quicker than the divide, since dividing is harder than multiplying.
  844. X */
  845. Xvoid
  846. Xzredcdecode(rp, z1, res)
  847. X    REDC *rp;        /* REDC information */
  848. X    ZVALUE z1;        /* number to be transformed */
  849. X    ZVALUE *res;        /* returned transformed number */
  850. X{
  851. X    ZVALUE tmp1, tmp2;    /* temporaries */
  852. X    HALF *hp;        /* saved pointer to tmp2 value */
  853. X
  854. X    if (isneg(z1))
  855. X        error("Negative number for zredc");
  856. X
  857. X    /*
  858. X     * Check first for the special values for 0 and 1 that are easy.
  859. X     */
  860. X    if (iszero(z1)) {
  861. X        *res = _zero_;
  862. X        return;
  863. X    }
  864. X    if ((z1.len == rp->one.len) && (z1.v[0] == rp->one.v[0]) &&
  865. X        (zcmp(z1, rp->one) == 0)) {
  866. X            *res = _one_;
  867. X            return;
  868. X    }
  869. X
  870. X    /*
  871. X     * First calculate the following:
  872. X     *     tmp2 = ((z1 % 2^bitnum) * inv) % 2^bitnum.
  873. X     * The mod operations can be done with no work since the bit
  874. X     * number was selected as a multiple of the word size.  Just
  875. X     * reduce the sizes of the numbers as required.
  876. X     */
  877. X    tmp1 = z1;
  878. X    if (tmp1.len > rp->len)
  879. X        tmp1.len = rp->len;
  880. X    zmul(tmp1, rp->inv, &tmp2);
  881. X    if (tmp2.len > rp->len)
  882. X        tmp2.len = rp->len;
  883. X
  884. X    /*
  885. X     * Next calculate the following:
  886. X     *    res = (z1 + tmp2 * modulus) / 2^bitnum
  887. X     * The division by a power of 2 is always exact, and requires no
  888. X     * work.  Just adjust the address and length of the number to do
  889. X     * the divide, but save the original pointer for freeing later.
  890. X     */
  891. X    zmul(tmp2, rp->mod, &tmp1);
  892. X    freeh(tmp2.v);
  893. X    zadd(z1, tmp1, &tmp2);
  894. X    freeh(tmp1.v);
  895. X    hp = tmp2.v;
  896. X    if (tmp2.len <= rp->len) {
  897. X        freeh(hp);
  898. X        *res = _zero_;
  899. X        return;
  900. X    }
  901. X    tmp2.v += rp->len;
  902. X    tmp2.len -= rp->len;
  903. X
  904. X    /*
  905. X     * Finally do a final modulo by a simple subtraction if necessary.
  906. X     * This is all that is needed because the previous calculation is
  907. X     * guaranteed to always be less than twice the modulus.
  908. X     */
  909. X    if (zrel(tmp2, rp->mod) < 0)
  910. X        zcopy(tmp2, res);
  911. X    else
  912. X        zsub(tmp2, rp->mod, res);
  913. X    freeh(hp);
  914. X}
  915. X
  916. X
  917. X/*
  918. X * Multiply two numbers in REDC format together producing a result also
  919. X * in REDC format.  If the result is converted back to a normal number,
  920. X * then the result is the same as the modulo'd multiplication of the
  921. X * original numbers before they were converted to REDC format.  This
  922. X * calculation is done in one of two ways, depending on the size of the
  923. X * modulus.  For large numbers, the REDC definition is used directly
  924. X * which involves three multiplies overall.  For small numbers, a
  925. X * complicated routine is used which does the indicated multiplication
  926. X * and the REDC algorithm at the same time to produce the result.
  927. X */
  928. Xvoid
  929. Xzredcmul(rp, z1, z2, res)
  930. X    REDC *rp;        /* REDC information */
  931. X    ZVALUE z1;        /* first REDC number to be multiplied */
  932. X    ZVALUE z2;        /* second REDC number to be multiplied */
  933. X    ZVALUE *res;        /* resulting REDC number */
  934. X{
  935. X    FULL mulb;
  936. X    FULL muln;
  937. X    HALF *h1;
  938. X    HALF *h2;
  939. X    HALF *h3;
  940. X    HALF *hd;
  941. X    HALF Ninv;
  942. X    HALF topdigit;
  943. X    LEN modlen;
  944. X    LEN len;
  945. X    LEN len2;
  946. X    SIUNION sival1;
  947. X    SIUNION sival2;
  948. X    SIUNION sival3;
  949. X    SIUNION carry;
  950. X    ZVALUE tmp;
  951. X
  952. X    if (isneg(z1) || (z1.len > rp->mod.len) ||
  953. X        isneg(z2) || (z2.len > rp->mod.len))
  954. X            error("Negative or too large number in zredcmul");
  955. X
  956. X    /*
  957. X     * Check for special values which we easily know the answer.
  958. X     */
  959. X    if (iszero(z1) || iszero(z2)) {
  960. X        *res = _zero_;
  961. X        return;
  962. X    }
  963. X
  964. X    if ((z1.len == rp->one.len) && (z1.v[0] == rp->one.v[0]) &&
  965. X        (zcmp(z1, rp->one) == 0)) {
  966. X            zcopy(z2, res);
  967. X            return;
  968. X    }
  969. X
  970. X    if ((z2.len == rp->one.len) && (z2.v[0] == rp->one.v[0]) &&
  971. X        (zcmp(z2, rp->one) == 0)) {
  972. X            zcopy(z1, res);
  973. X            return;
  974. X    }
  975. X
  976. X    /*
  977. X     * If the size of the modulus is large, then just do the multiply,
  978. X     * followed by the two multiplies contained in the REDC routine.
  979. X     * This will be quicker than directly doing the REDC calculation
  980. X     * because of the O(N^1.585) speed of the multiplies.  The size
  981. X     * of the number which this is done is configurable.
  982. X     */
  983. X    if (rp->mod.len >= _redc2_) {
  984. X        zmul(z1, z2, &tmp);
  985. X        zredcdecode(rp, tmp, res);
  986. X        freeh(tmp.v);
  987. X        return;
  988. X    }
  989. X
  990. X    /*
  991. X     * The number is small enough to calculate by doing the O(N^2) REDC
  992. X     * algorithm directly.  This algorithm performs the multiplication and
  993. X     * the reduction at the same time.  Notice the obscure facts that
  994. X     * only the lowest word of the inverse value is used, and that
  995. X     * there is no shifting of the partial products as there is in a
  996. X     * normal multiply.
  997. X     */
  998. X    modlen = rp->mod.len;
  999. X    Ninv = rp->inv.v[0];
  1000. X
  1001. X    /*
  1002. X     * Allocate the result and clear it.
  1003. X     * The size of the result will be equal to or smaller than
  1004. X     * the modulus size.
  1005. X     */
  1006. X    res->sign = 0;
  1007. X    res->len = modlen;
  1008. X    res->v = alloc(modlen);
  1009. X
  1010. X    hd = res->v;
  1011. X    len = modlen;
  1012. X    while (len--)
  1013. X        *hd++ = 0;
  1014. X
  1015. X    /*
  1016. X     * Do this outermost loop over all the digits of z1.
  1017. X     */
  1018. X    h1 = z1.v;
  1019. X    len = z1.len;
  1020. X    while (len--) {
  1021. X        /*
  1022. X         * Start off with the next digit of z1, the first
  1023. X         * digit of z2, and the first digit of the modulus.
  1024. X         */
  1025. X        mulb = (FULL) *h1++;
  1026. X        h2 = z2.v;
  1027. X        h3 = rp->mod.v;
  1028. X        hd = res->v;
  1029. X        sival1.ivalue = mulb * ((FULL) *h2++) + ((FULL) *hd++);
  1030. X        muln = ((HALF) (sival1.silow * Ninv));
  1031. X        sival2.ivalue = muln * ((FULL) *h3++);
  1032. X        sival3.ivalue = ((FULL) sival1.silow) + ((FULL) sival2.silow);
  1033. X        carry.ivalue = ((FULL) sival1.sihigh) + ((FULL) sival2.sihigh)
  1034. X            + ((FULL) sival3.sihigh);
  1035. X
  1036. X        /*
  1037. X         * Do this innermost loop for each digit of z2, except
  1038. X         * for the first digit which was just done above.
  1039. X         */
  1040. X        len2 = z2.len;
  1041. X        while (--len2 > 0) {
  1042. X            sival1.ivalue = mulb * ((FULL) *h2++);
  1043. X            sival2.ivalue = muln * ((FULL) *h3++);
  1044. X            sival3.ivalue = ((FULL) sival1.silow)
  1045. X                + ((FULL) sival2.silow)
  1046. X                + ((FULL) *hd)
  1047. X                + ((FULL) carry.silow);
  1048. X            carry.ivalue = ((FULL) sival1.sihigh)
  1049. X                + ((FULL) sival2.sihigh)
  1050. X                + ((FULL) sival3.sihigh)
  1051. X                + ((FULL) carry.sihigh);
  1052. X
  1053. X            hd[-1] = sival3.silow;
  1054. X            hd++;
  1055. X        }
  1056. X
  1057. X        /*
  1058. X         * Now continue the loop as necessary so the total number
  1059. X         * of interations is equal to the size of the modulus.
  1060. X         * This acts as if the innermost loop was repeated for
  1061. X         * high digits of z2 that are zero.
  1062. X         */
  1063. X        len2 = modlen - z2.len;
  1064. X        while (len2--) {
  1065. X            sival2.ivalue = muln * ((FULL) *h3++);
  1066. X            sival3.ivalue = ((FULL) sival2.silow)
  1067. X                + ((FULL) *hd)
  1068. X                + ((FULL) carry.silow);
  1069. X            carry.ivalue = ((FULL) sival2.sihigh)
  1070. X                + ((FULL) sival3.sihigh)
  1071. X                + ((FULL) carry.sihigh);
  1072. X
  1073. X            hd[-1] = sival3.silow;
  1074. X            hd++;
  1075. X        }
  1076. X
  1077. X        res->v[modlen - 1] = carry.silow;
  1078. X        topdigit = carry.sihigh;
  1079. X    }
  1080. X
  1081. X    /*
  1082. X     * Now continue the loop as necessary so the total number
  1083. X     * of interations is equal to the size of the modulus.
  1084. X     * This acts as if the outermost loop was repeated for high
  1085. X     * digits of z1 that are zero.
  1086. X     */
  1087. X    len = modlen - z1.len;
  1088. X    while (len--) {
  1089. X        /*
  1090. X         * Start off with the first digit of the modulus.
  1091. X         */
  1092. X        h3 = rp->mod.v;
  1093. X        hd = res->v;
  1094. X        muln = ((HALF) (*hd * Ninv));
  1095. X        sival2.ivalue = muln * ((FULL) *h3++);
  1096. X        sival3.ivalue = ((FULL) *hd++) + ((FULL) sival2.silow);
  1097. X        carry.ivalue = ((FULL) sival2.sihigh) + ((FULL) sival3.sihigh);
  1098. X
  1099. X        /*
  1100. X         * Do this innermost loop for each digit of the modulus,
  1101. X         * except for the first digit which was just done above.
  1102. X         */
  1103. X        len2 = modlen;
  1104. X        while (--len2 > 0) {
  1105. X            sival2.ivalue = muln * ((FULL) *h3++);
  1106. X            sival3.ivalue = ((FULL) sival2.silow)
  1107. X                + ((FULL) *hd)
  1108. X                + ((FULL) carry.silow);
  1109. X            carry.ivalue = ((FULL) sival2.sihigh)
  1110. X                + ((FULL) sival3.sihigh)
  1111. X                + ((FULL) carry.sihigh);
  1112. X
  1113. X            hd[-1] = sival3.silow;
  1114. X            hd++;
  1115. X        }
  1116. X        res->v[modlen - 1] = carry.silow;
  1117. X        topdigit = carry.sihigh;
  1118. X    }
  1119. X
  1120. X    /*
  1121. X     * Determine the true size of the result, taking the top digit of
  1122. X     * the current result into account.  The top digit is not stored in
  1123. X     * the number because it is temporary and would become zero anyway
  1124. X     * after the final subtraction is done.
  1125. X     */
  1126. X    if (topdigit == 0) {
  1127. X        len = modlen;
  1128. X        hd = &res->v[len - 1];
  1129. X        while ((*hd == 0) && (len > 1)) {
  1130. X            hd--;
  1131. X            len--;
  1132. X        }
  1133. X        res->len = len;
  1134. X    }
  1135. X
  1136. X    /*
  1137. X     * Compare the result with the modulus.
  1138. X     * If it is less than the modulus, then the calculation is complete.
  1139. X     */
  1140. X    if ((topdigit == 0) && ((len < modlen)
  1141. X        || (res->v[len - 1] < rp->mod.v[len - 1])
  1142. X        || (zrel(*res, rp->mod) < 0)))
  1143. X            return;
  1144. X
  1145. X    /*
  1146. X     * Do a subtraction to reduce the result to a value less than
  1147. X     * the modulus.  The REDC algorithm guarantees that a single subtract
  1148. X     * is all that is needed.  Ignore any borrowing from the possible
  1149. X     * highest word of the current result because that would affect
  1150. X     * only the top digit value that was not stored and would become
  1151. X     * zero anyway.
  1152. X     */
  1153. X    carry.ivalue = 0;
  1154. X    h1 = rp->mod.v;
  1155. X    hd = res->v;
  1156. X    len = modlen;
  1157. X    while (len--) {
  1158. X        carry.ivalue = BASE1 - ((FULL) *hd) + ((FULL) *h1++)
  1159. X            + ((FULL) carry.silow);
  1160. X        *hd++ = BASE1 - carry.silow;
  1161. X        carry.silow = carry.sihigh;
  1162. X    }
  1163. X
  1164. X    /*
  1165. X     * Now finally recompute the size of the result.
  1166. X     */
  1167. X    len = modlen;
  1168. X    hd = &res->v[len - 1];
  1169. X    while ((*hd == 0) && (len > 1)) {
  1170. X        hd--;
  1171. X        len--;
  1172. X    }
  1173. X    res->len = len;
  1174. X}
  1175. X
  1176. X
  1177. X/*
  1178. X * Square a number in REDC format producing a result also in REDC format.
  1179. X */
  1180. Xvoid
  1181. Xzredcsquare(rp, z1, res)
  1182. X    REDC *rp;        /* REDC information */
  1183. X    ZVALUE z1;        /* REDC number to be squared */
  1184. X    ZVALUE *res;        /* resulting REDC number */
  1185. X{
  1186. X    ZVALUE tmp;
  1187. X
  1188. X    if (isneg(z1))
  1189. X        error("Negative number in zredcsquare");
  1190. X    if (iszero(z1)) {
  1191. X        *res = _zero_;
  1192. X        return;
  1193. X    }
  1194. X    if ((z1.len == rp->one.len) && (z1.v[0] == rp->one.v[0]) &&
  1195. X        (zcmp(z1, rp->one) == 0)) {
  1196. X            zcopy(z1, res);
  1197. X            return;
  1198. X    }
  1199. X
  1200. X    /*
  1201. X     * If the modulus is small enough, then call the multiply
  1202. X     * routine to produce the result.  Otherwise call the O(N^1.585)
  1203. X     * routines to get the answer.
  1204. X     */
  1205. X    if (rp->mod.len < _redc2_) {
  1206. X        zredcmul(rp, z1, z1, res);
  1207. X        return;
  1208. X    }
  1209. X    zsquare(z1, &tmp);
  1210. X    zredcdecode(rp, tmp, res);
  1211. X    freeh(tmp.v);
  1212. X}
  1213. X
  1214. X
  1215. X/*
  1216. X * Compute the result of raising a REDC format number to a power.
  1217. X * The result is within the range 0 to the modulus - 1.
  1218. X * This calculates the result by examining the power POWBITS bits at a time,
  1219. X * using a small table of POWNUMS low powers to calculate powers for those bits,
  1220. X * and repeated squaring and multiplying by the partial powers to generate
  1221. X * the complete power.
  1222. X */
  1223. Xvoid
  1224. Xzredcpower(rp, z1, z2, res)
  1225. X    REDC *rp;        /* REDC information */
  1226. X    ZVALUE z1;        /* REDC number to be raised */
  1227. X    ZVALUE z2;        /* normal number to raise number to */
  1228. X    ZVALUE *res;        /* result */
  1229. X{
  1230. X    HALF *hp;        /* pointer to current word of the power */
  1231. X    ZVALUE *pp;        /* pointer to low power table */
  1232. X    ZVALUE ans, temp;    /* calculation values */
  1233. X    ZVALUE modpow;        /* current small power */
  1234. X    ZVALUE lowpowers[POWNUMS];    /* low powers */
  1235. X    int curshift;        /* shift value for word of power */
  1236. X    HALF curhalf;        /* current word of power */
  1237. X    unsigned int curpow;    /* current low power */
  1238. X    unsigned int curbit;    /* current bit of low power */
  1239. X    int i;
  1240. X
  1241. X    if (isneg(z1))
  1242. X        error("Negative number in zredcpower");
  1243. X    if (isneg(z2))
  1244. X        error("Negative power in zredcpower");
  1245. X
  1246. X    /*
  1247. X     * Check for zero or the REDC format for one.
  1248. X     */
  1249. X    if (iszero(z1) || isunit(rp->mod)) {
  1250. X        *res = _zero_;
  1251. X        return;
  1252. X    }
  1253. X    if (zcmp(z1, rp->one) == 0) {
  1254. X        zcopy(rp->one, res);
  1255. X        return;
  1256. X    }
  1257. X
  1258. X    /*
  1259. X     * See if the number being raised is the REDC format for -1.
  1260. X     * If so, then the answer is the REDC format for one or minus one.
  1261. X     * To do this check, calculate the REDC format for -1.
  1262. X     */
  1263. X    if (((HALF)(z1.v[0] + rp->one.v[0])) == rp->mod.v[0]) {
  1264. X        zsub(rp->mod, rp->one, &temp);
  1265. X        if (zcmp(z1, temp) == 0) {
  1266. X            if (isodd(z2)) {
  1267. X                *res = temp;
  1268. X                return;
  1269. X            }
  1270. X            freeh(temp.v);
  1271. X            zcopy(rp->one, res);
  1272. X            return;
  1273. X        }
  1274. X        freeh(temp.v);
  1275. X    }
  1276. X
  1277. X    for (pp = &lowpowers[2]; pp < &lowpowers[POWNUMS]; pp++)
  1278. X        pp->len = 0;
  1279. X    zcopy(rp->one, &lowpowers[0]);
  1280. X    zcopy(z1, &lowpowers[1]);
  1281. X    zcopy(rp->one, &ans);
  1282. X
  1283. X    hp = &z2.v[z2.len - 1];
  1284. X    curhalf = *hp;
  1285. X    curshift = BASEB - POWBITS;
  1286. X    while (curshift && ((curhalf >> curshift) == 0))
  1287. X        curshift -= POWBITS;
  1288. X
  1289. X    /*
  1290. X     * Calculate the result by examining the power POWBITS bits at a time,
  1291. X     * and use the table of low powers at each iteration.
  1292. X     */
  1293. X    for (;;) {
  1294. X        curpow = (curhalf >> curshift) & (POWNUMS - 1);
  1295. X        pp = &lowpowers[curpow];
  1296. X
  1297. X        /*
  1298. X         * If the small power is not yet saved in the table, then
  1299. X         * calculate it and remember it in the table for future use.
  1300. X         */
  1301. X        if (pp->len == 0) {
  1302. X            if (curpow & 0x1)
  1303. X                zcopy(z1, &modpow);
  1304. X            else
  1305. X                zcopy(rp->one, &modpow);
  1306. X
  1307. X            for (curbit = 0x2; curbit <= curpow; curbit *= 2) {
  1308. X                pp = &lowpowers[curbit];
  1309. X                if (pp->len == 0)
  1310. X                    zredcsquare(rp, lowpowers[curbit/2],
  1311. X                        pp);
  1312. X                if (curbit & curpow) {
  1313. X                    zredcmul(rp, *pp, modpow, &temp);
  1314. X                    freeh(modpow.v);
  1315. X                    modpow = temp;
  1316. X                }
  1317. X            }
  1318. X            pp = &lowpowers[curpow];
  1319. X            *pp = modpow;
  1320. X        }
  1321. X
  1322. X        /*
  1323. X         * If the power is nonzero, then accumulate the small power
  1324. X         * into the result.
  1325. X         */
  1326. X        if (curpow) {
  1327. X            zredcmul(rp, ans, *pp, &temp);
  1328. X            freeh(ans.v);
  1329. X            ans = temp;
  1330. X        }
  1331. X
  1332. X        /*
  1333. X         * Select the next POWBITS bits of the power, if there is
  1334. X         * any more to generate.
  1335. X         */
  1336. X        curshift -= POWBITS;
  1337. X        if (curshift < 0) {
  1338. X            if (hp-- == z2.v)
  1339. X                break;
  1340. X            curhalf = *hp;
  1341. X            curshift = BASEB - POWBITS;
  1342. X        }
  1343. X
  1344. X        /*
  1345. X         * Square the result POWBITS times to make room for the next
  1346. X         * chunk of bits.
  1347. X         */
  1348. X        for (i = 0; i < POWBITS; i++) {
  1349. X            zredcsquare(rp, ans, &temp);
  1350. X            freeh(ans.v);
  1351. X            ans = temp;
  1352. X        }
  1353. X    }
  1354. X
  1355. X    for (pp = lowpowers; pp < &lowpowers[POWNUMS]; pp++) {
  1356. X        if (pp->len)
  1357. X            freeh(pp->v);
  1358. X    }
  1359. X    *res = ans;
  1360. X}
  1361. X
  1362. X/* END CODE */
  1363. END_OF_FILE
  1364. if test 32468 -ne `wc -c <'zmod.c'`; then
  1365.     echo shar: \"'zmod.c'\" unpacked with wrong size!
  1366. fi
  1367. # end of 'zmod.c'
  1368. fi
  1369. echo shar: End of archive 16 \(of 21\).
  1370. cp /dev/null ark16isdone
  1371. MISSING=""
  1372. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  1373.     if test ! -f ark${I}isdone ; then
  1374.     MISSING="${MISSING} ${I}"
  1375.     fi
  1376. done
  1377. if test "${MISSING}" = "" ; then
  1378.     echo You have unpacked all 21 archives.
  1379.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1380. else
  1381.     echo You still need to unpack the following archives:
  1382.     echo "        " ${MISSING}
  1383. fi
  1384. ##  End of shell archive.
  1385. exit 0
  1386.