xref: /onnv-gate/usr/src/common/mpi/mpi.c (revision 5697)
1*5697Smcpowers /*
2*5697Smcpowers  *  mpi.c
3*5697Smcpowers  *
4*5697Smcpowers  *  Arbitrary precision integer arithmetic library
5*5697Smcpowers  *
6*5697Smcpowers  * ***** BEGIN LICENSE BLOCK *****
7*5697Smcpowers  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
8*5697Smcpowers  *
9*5697Smcpowers  * The contents of this file are subject to the Mozilla Public License Version
10*5697Smcpowers  * 1.1 (the "License"); you may not use this file except in compliance with
11*5697Smcpowers  * the License. You may obtain a copy of the License at
12*5697Smcpowers  * http://www.mozilla.org/MPL/
13*5697Smcpowers  *
14*5697Smcpowers  * Software distributed under the License is distributed on an "AS IS" basis,
15*5697Smcpowers  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16*5697Smcpowers  * for the specific language governing rights and limitations under the
17*5697Smcpowers  * License.
18*5697Smcpowers  *
19*5697Smcpowers  * The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.
20*5697Smcpowers  *
21*5697Smcpowers  * The Initial Developer of the Original Code is
22*5697Smcpowers  * Michael J. Fromberger.
23*5697Smcpowers  * Portions created by the Initial Developer are Copyright (C) 1998
24*5697Smcpowers  * the Initial Developer. All Rights Reserved.
25*5697Smcpowers  *
26*5697Smcpowers  * Contributor(s):
27*5697Smcpowers  *   Netscape Communications Corporation
28*5697Smcpowers  *   Douglas Stebila <douglas@stebila.ca> of Sun Laboratories.
29*5697Smcpowers  *
30*5697Smcpowers  * Alternatively, the contents of this file may be used under the terms of
31*5697Smcpowers  * either the GNU General Public License Version 2 or later (the "GPL"), or
32*5697Smcpowers  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
33*5697Smcpowers  * in which case the provisions of the GPL or the LGPL are applicable instead
34*5697Smcpowers  * of those above. If you wish to allow use of your version of this file only
35*5697Smcpowers  * under the terms of either the GPL or the LGPL, and not to allow others to
36*5697Smcpowers  * use your version of this file under the terms of the MPL, indicate your
37*5697Smcpowers  * decision by deleting the provisions above and replace them with the notice
38*5697Smcpowers  * and other provisions required by the GPL or the LGPL. If you do not delete
39*5697Smcpowers  * the provisions above, a recipient may use your version of this file under
40*5697Smcpowers  * the terms of any one of the MPL, the GPL or the LGPL.
41*5697Smcpowers  *
42*5697Smcpowers  * ***** END LICENSE BLOCK ***** */
43*5697Smcpowers /*
44*5697Smcpowers  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
45*5697Smcpowers  * Use is subject to license terms.
46*5697Smcpowers  *
47*5697Smcpowers  * Sun elects to use this software under the MPL license.
48*5697Smcpowers  */
49*5697Smcpowers 
50*5697Smcpowers #pragma ident	"%Z%%M%	%I%	%E% SMI"
51*5697Smcpowers 
52*5697Smcpowers /* $Id: mpi.c,v 1.45 2006/09/29 20:12:21 alexei.volkov.bugs%sun.com Exp $ */
53*5697Smcpowers 
54*5697Smcpowers #include "mpi-priv.h"
55*5697Smcpowers #if defined(OSF1)
56*5697Smcpowers #include <c_asm.h>
57*5697Smcpowers #endif
58*5697Smcpowers 
59*5697Smcpowers #if MP_LOGTAB
60*5697Smcpowers /*
61*5697Smcpowers   A table of the logs of 2 for various bases (the 0 and 1 entries of
62*5697Smcpowers   this table are meaningless and should not be referenced).
63*5697Smcpowers 
64*5697Smcpowers   This table is used to compute output lengths for the mp_toradix()
65*5697Smcpowers   function.  Since a number n in radix r takes up about log_r(n)
66*5697Smcpowers   digits, we estimate the output size by taking the least integer
67*5697Smcpowers   greater than log_r(n), where:
68*5697Smcpowers 
69*5697Smcpowers   log_r(n) = log_2(n) * log_r(2)
70*5697Smcpowers 
71*5697Smcpowers   This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
72*5697Smcpowers   which are the output bases supported.
73*5697Smcpowers  */
74*5697Smcpowers #include "logtab.h"
75*5697Smcpowers #endif
76*5697Smcpowers 
77*5697Smcpowers /* {{{ Constant strings */
78*5697Smcpowers 
79*5697Smcpowers /* Constant strings returned by mp_strerror() */
80*5697Smcpowers static const char *mp_err_string[] = {
81*5697Smcpowers   "unknown result code",     /* say what?            */
82*5697Smcpowers   "boolean true",            /* MP_OKAY, MP_YES      */
83*5697Smcpowers   "boolean false",           /* MP_NO                */
84*5697Smcpowers   "out of memory",           /* MP_MEM               */
85*5697Smcpowers   "argument out of range",   /* MP_RANGE             */
86*5697Smcpowers   "invalid input parameter", /* MP_BADARG            */
87*5697Smcpowers   "result is undefined"      /* MP_UNDEF             */
88*5697Smcpowers };
89*5697Smcpowers 
90*5697Smcpowers /* Value to digit maps for radix conversion   */
91*5697Smcpowers 
92*5697Smcpowers /* s_dmap_1 - standard digits and letters */
93*5697Smcpowers static const char *s_dmap_1 =
94*5697Smcpowers   "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
95*5697Smcpowers 
96*5697Smcpowers /* }}} */
97*5697Smcpowers 
98*5697Smcpowers unsigned long mp_allocs;
99*5697Smcpowers unsigned long mp_frees;
100*5697Smcpowers unsigned long mp_copies;
101*5697Smcpowers 
102*5697Smcpowers /* {{{ Default precision manipulation */
103*5697Smcpowers 
104*5697Smcpowers /* Default precision for newly created mp_int's      */
105*5697Smcpowers static mp_size s_mp_defprec = MP_DEFPREC;
106*5697Smcpowers 
107*5697Smcpowers mp_size mp_get_prec(void)
108*5697Smcpowers {
109*5697Smcpowers   return s_mp_defprec;
110*5697Smcpowers 
111*5697Smcpowers } /* end mp_get_prec() */
112*5697Smcpowers 
113*5697Smcpowers void         mp_set_prec(mp_size prec)
114*5697Smcpowers {
115*5697Smcpowers   if(prec == 0)
116*5697Smcpowers     s_mp_defprec = MP_DEFPREC;
117*5697Smcpowers   else
118*5697Smcpowers     s_mp_defprec = prec;
119*5697Smcpowers 
120*5697Smcpowers } /* end mp_set_prec() */
121*5697Smcpowers 
122*5697Smcpowers /* }}} */
123*5697Smcpowers 
124*5697Smcpowers /*------------------------------------------------------------------------*/
125*5697Smcpowers /* {{{ mp_init(mp, kmflag) */
126*5697Smcpowers 
127*5697Smcpowers /*
128*5697Smcpowers   mp_init(mp, kmflag)
129*5697Smcpowers 
130*5697Smcpowers   Initialize a new zero-valued mp_int.  Returns MP_OKAY if successful,
131*5697Smcpowers   MP_MEM if memory could not be allocated for the structure.
132*5697Smcpowers  */
133*5697Smcpowers 
134*5697Smcpowers mp_err mp_init(mp_int *mp, int kmflag)
135*5697Smcpowers {
136*5697Smcpowers   return mp_init_size(mp, s_mp_defprec, kmflag);
137*5697Smcpowers 
138*5697Smcpowers } /* end mp_init() */
139*5697Smcpowers 
140*5697Smcpowers /* }}} */
141*5697Smcpowers 
142*5697Smcpowers /* {{{ mp_init_size(mp, prec, kmflag) */
143*5697Smcpowers 
144*5697Smcpowers /*
145*5697Smcpowers   mp_init_size(mp, prec, kmflag)
146*5697Smcpowers 
147*5697Smcpowers   Initialize a new zero-valued mp_int with at least the given
148*5697Smcpowers   precision; returns MP_OKAY if successful, or MP_MEM if memory could
149*5697Smcpowers   not be allocated for the structure.
150*5697Smcpowers  */
151*5697Smcpowers 
152*5697Smcpowers mp_err mp_init_size(mp_int *mp, mp_size prec, int kmflag)
153*5697Smcpowers {
154*5697Smcpowers   ARGCHK(mp != NULL && prec > 0, MP_BADARG);
155*5697Smcpowers 
156*5697Smcpowers   prec = MP_ROUNDUP(prec, s_mp_defprec);
157*5697Smcpowers   if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit), kmflag)) == NULL)
158*5697Smcpowers     return MP_MEM;
159*5697Smcpowers 
160*5697Smcpowers   SIGN(mp) = ZPOS;
161*5697Smcpowers   USED(mp) = 1;
162*5697Smcpowers   ALLOC(mp) = prec;
163*5697Smcpowers 
164*5697Smcpowers   return MP_OKAY;
165*5697Smcpowers 
166*5697Smcpowers } /* end mp_init_size() */
167*5697Smcpowers 
168*5697Smcpowers /* }}} */
169*5697Smcpowers 
170*5697Smcpowers /* {{{ mp_init_copy(mp, from) */
171*5697Smcpowers 
172*5697Smcpowers /*
173*5697Smcpowers   mp_init_copy(mp, from)
174*5697Smcpowers 
175*5697Smcpowers   Initialize mp as an exact copy of from.  Returns MP_OKAY if
176*5697Smcpowers   successful, MP_MEM if memory could not be allocated for the new
177*5697Smcpowers   structure.
178*5697Smcpowers  */
179*5697Smcpowers 
180*5697Smcpowers mp_err mp_init_copy(mp_int *mp, const mp_int *from)
181*5697Smcpowers {
182*5697Smcpowers   ARGCHK(mp != NULL && from != NULL, MP_BADARG);
183*5697Smcpowers 
184*5697Smcpowers   if(mp == from)
185*5697Smcpowers     return MP_OKAY;
186*5697Smcpowers 
187*5697Smcpowers   if((DIGITS(mp) = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)
188*5697Smcpowers     return MP_MEM;
189*5697Smcpowers 
190*5697Smcpowers   s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
191*5697Smcpowers   USED(mp) = USED(from);
192*5697Smcpowers   ALLOC(mp) = ALLOC(from);
193*5697Smcpowers   SIGN(mp) = SIGN(from);
194*5697Smcpowers   FLAG(mp) = FLAG(from);
195*5697Smcpowers 
196*5697Smcpowers   return MP_OKAY;
197*5697Smcpowers 
198*5697Smcpowers } /* end mp_init_copy() */
199*5697Smcpowers 
200*5697Smcpowers /* }}} */
201*5697Smcpowers 
202*5697Smcpowers /* {{{ mp_copy(from, to) */
203*5697Smcpowers 
204*5697Smcpowers /*
205*5697Smcpowers   mp_copy(from, to)
206*5697Smcpowers 
207*5697Smcpowers   Copies the mp_int 'from' to the mp_int 'to'.  It is presumed that
208*5697Smcpowers   'to' has already been initialized (if not, use mp_init_copy()
209*5697Smcpowers   instead). If 'from' and 'to' are identical, nothing happens.
210*5697Smcpowers  */
211*5697Smcpowers 
212*5697Smcpowers mp_err mp_copy(const mp_int *from, mp_int *to)
213*5697Smcpowers {
214*5697Smcpowers   ARGCHK(from != NULL && to != NULL, MP_BADARG);
215*5697Smcpowers 
216*5697Smcpowers   if(from == to)
217*5697Smcpowers     return MP_OKAY;
218*5697Smcpowers 
219*5697Smcpowers   ++mp_copies;
220*5697Smcpowers   { /* copy */
221*5697Smcpowers     mp_digit   *tmp;
222*5697Smcpowers 
223*5697Smcpowers     /*
224*5697Smcpowers       If the allocated buffer in 'to' already has enough space to hold
225*5697Smcpowers       all the used digits of 'from', we'll re-use it to avoid hitting
226*5697Smcpowers       the memory allocater more than necessary; otherwise, we'd have
227*5697Smcpowers       to grow anyway, so we just allocate a hunk and make the copy as
228*5697Smcpowers       usual
229*5697Smcpowers      */
230*5697Smcpowers     if(ALLOC(to) >= USED(from)) {
231*5697Smcpowers       s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));
232*5697Smcpowers       s_mp_copy(DIGITS(from), DIGITS(to), USED(from));
233*5697Smcpowers 
234*5697Smcpowers     } else {
235*5697Smcpowers       if((tmp = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)
236*5697Smcpowers 	return MP_MEM;
237*5697Smcpowers 
238*5697Smcpowers       s_mp_copy(DIGITS(from), tmp, USED(from));
239*5697Smcpowers 
240*5697Smcpowers       if(DIGITS(to) != NULL) {
241*5697Smcpowers #if MP_CRYPTO
242*5697Smcpowers 	s_mp_setz(DIGITS(to), ALLOC(to));
243*5697Smcpowers #endif
244*5697Smcpowers 	s_mp_free(DIGITS(to), ALLOC(to));
245*5697Smcpowers       }
246*5697Smcpowers 
247*5697Smcpowers       DIGITS(to) = tmp;
248*5697Smcpowers       ALLOC(to) = ALLOC(from);
249*5697Smcpowers     }
250*5697Smcpowers 
251*5697Smcpowers     /* Copy the precision and sign from the original */
252*5697Smcpowers     USED(to) = USED(from);
253*5697Smcpowers     SIGN(to) = SIGN(from);
254*5697Smcpowers   } /* end copy */
255*5697Smcpowers 
256*5697Smcpowers   return MP_OKAY;
257*5697Smcpowers 
258*5697Smcpowers } /* end mp_copy() */
259*5697Smcpowers 
260*5697Smcpowers /* }}} */
261*5697Smcpowers 
262*5697Smcpowers /* {{{ mp_exch(mp1, mp2) */
263*5697Smcpowers 
264*5697Smcpowers /*
265*5697Smcpowers   mp_exch(mp1, mp2)
266*5697Smcpowers 
267*5697Smcpowers   Exchange mp1 and mp2 without allocating any intermediate memory
268*5697Smcpowers   (well, unless you count the stack space needed for this call and the
269*5697Smcpowers   locals it creates...).  This cannot fail.
270*5697Smcpowers  */
271*5697Smcpowers 
272*5697Smcpowers void mp_exch(mp_int *mp1, mp_int *mp2)
273*5697Smcpowers {
274*5697Smcpowers #if MP_ARGCHK == 2
275*5697Smcpowers   assert(mp1 != NULL && mp2 != NULL);
276*5697Smcpowers #else
277*5697Smcpowers   if(mp1 == NULL || mp2 == NULL)
278*5697Smcpowers     return;
279*5697Smcpowers #endif
280*5697Smcpowers 
281*5697Smcpowers   s_mp_exch(mp1, mp2);
282*5697Smcpowers 
283*5697Smcpowers } /* end mp_exch() */
284*5697Smcpowers 
285*5697Smcpowers /* }}} */
286*5697Smcpowers 
287*5697Smcpowers /* {{{ mp_clear(mp) */
288*5697Smcpowers 
289*5697Smcpowers /*
290*5697Smcpowers   mp_clear(mp)
291*5697Smcpowers 
292*5697Smcpowers   Release the storage used by an mp_int, and void its fields so that
293*5697Smcpowers   if someone calls mp_clear() again for the same int later, we won't
294*5697Smcpowers   get tollchocked.
295*5697Smcpowers  */
296*5697Smcpowers 
297*5697Smcpowers void   mp_clear(mp_int *mp)
298*5697Smcpowers {
299*5697Smcpowers   if(mp == NULL)
300*5697Smcpowers     return;
301*5697Smcpowers 
302*5697Smcpowers   if(DIGITS(mp) != NULL) {
303*5697Smcpowers #if MP_CRYPTO
304*5697Smcpowers     s_mp_setz(DIGITS(mp), ALLOC(mp));
305*5697Smcpowers #endif
306*5697Smcpowers     s_mp_free(DIGITS(mp), ALLOC(mp));
307*5697Smcpowers     DIGITS(mp) = NULL;
308*5697Smcpowers   }
309*5697Smcpowers 
310*5697Smcpowers   USED(mp) = 0;
311*5697Smcpowers   ALLOC(mp) = 0;
312*5697Smcpowers 
313*5697Smcpowers } /* end mp_clear() */
314*5697Smcpowers 
315*5697Smcpowers /* }}} */
316*5697Smcpowers 
317*5697Smcpowers /* {{{ mp_zero(mp) */
318*5697Smcpowers 
319*5697Smcpowers /*
320*5697Smcpowers   mp_zero(mp)
321*5697Smcpowers 
322*5697Smcpowers   Set mp to zero.  Does not change the allocated size of the structure,
323*5697Smcpowers   and therefore cannot fail (except on a bad argument, which we ignore)
324*5697Smcpowers  */
325*5697Smcpowers void   mp_zero(mp_int *mp)
326*5697Smcpowers {
327*5697Smcpowers   if(mp == NULL)
328*5697Smcpowers     return;
329*5697Smcpowers 
330*5697Smcpowers   s_mp_setz(DIGITS(mp), ALLOC(mp));
331*5697Smcpowers   USED(mp) = 1;
332*5697Smcpowers   SIGN(mp) = ZPOS;
333*5697Smcpowers 
334*5697Smcpowers } /* end mp_zero() */
335*5697Smcpowers 
336*5697Smcpowers /* }}} */
337*5697Smcpowers 
338*5697Smcpowers /* {{{ mp_set(mp, d) */
339*5697Smcpowers 
340*5697Smcpowers void   mp_set(mp_int *mp, mp_digit d)
341*5697Smcpowers {
342*5697Smcpowers   if(mp == NULL)
343*5697Smcpowers     return;
344*5697Smcpowers 
345*5697Smcpowers   mp_zero(mp);
346*5697Smcpowers   DIGIT(mp, 0) = d;
347*5697Smcpowers 
348*5697Smcpowers } /* end mp_set() */
349*5697Smcpowers 
350*5697Smcpowers /* }}} */
351*5697Smcpowers 
352*5697Smcpowers /* {{{ mp_set_int(mp, z) */
353*5697Smcpowers 
354*5697Smcpowers mp_err mp_set_int(mp_int *mp, long z)
355*5697Smcpowers {
356*5697Smcpowers   int            ix;
357*5697Smcpowers   unsigned long  v = labs(z);
358*5697Smcpowers   mp_err         res;
359*5697Smcpowers 
360*5697Smcpowers   ARGCHK(mp != NULL, MP_BADARG);
361*5697Smcpowers 
362*5697Smcpowers   mp_zero(mp);
363*5697Smcpowers   if(z == 0)
364*5697Smcpowers     return MP_OKAY;  /* shortcut for zero */
365*5697Smcpowers 
366*5697Smcpowers   if (sizeof v <= sizeof(mp_digit)) {
367*5697Smcpowers     DIGIT(mp,0) = v;
368*5697Smcpowers   } else {
369*5697Smcpowers     for (ix = sizeof(long) - 1; ix >= 0; ix--) {
370*5697Smcpowers       if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
371*5697Smcpowers 	return res;
372*5697Smcpowers 
373*5697Smcpowers       res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
374*5697Smcpowers       if (res != MP_OKAY)
375*5697Smcpowers 	return res;
376*5697Smcpowers     }
377*5697Smcpowers   }
378*5697Smcpowers   if(z < 0)
379*5697Smcpowers     SIGN(mp) = NEG;
380*5697Smcpowers 
381*5697Smcpowers   return MP_OKAY;
382*5697Smcpowers 
383*5697Smcpowers } /* end mp_set_int() */
384*5697Smcpowers 
385*5697Smcpowers /* }}} */
386*5697Smcpowers 
387*5697Smcpowers /* {{{ mp_set_ulong(mp, z) */
388*5697Smcpowers 
389*5697Smcpowers mp_err mp_set_ulong(mp_int *mp, unsigned long z)
390*5697Smcpowers {
391*5697Smcpowers   int            ix;
392*5697Smcpowers   mp_err         res;
393*5697Smcpowers 
394*5697Smcpowers   ARGCHK(mp != NULL, MP_BADARG);
395*5697Smcpowers 
396*5697Smcpowers   mp_zero(mp);
397*5697Smcpowers   if(z == 0)
398*5697Smcpowers     return MP_OKAY;  /* shortcut for zero */
399*5697Smcpowers 
400*5697Smcpowers   if (sizeof z <= sizeof(mp_digit)) {
401*5697Smcpowers     DIGIT(mp,0) = z;
402*5697Smcpowers   } else {
403*5697Smcpowers     for (ix = sizeof(long) - 1; ix >= 0; ix--) {
404*5697Smcpowers       if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)
405*5697Smcpowers 	return res;
406*5697Smcpowers 
407*5697Smcpowers       res = s_mp_add_d(mp, (mp_digit)((z >> (ix * CHAR_BIT)) & UCHAR_MAX));
408*5697Smcpowers       if (res != MP_OKAY)
409*5697Smcpowers 	return res;
410*5697Smcpowers     }
411*5697Smcpowers   }
412*5697Smcpowers   return MP_OKAY;
413*5697Smcpowers } /* end mp_set_ulong() */
414*5697Smcpowers 
415*5697Smcpowers /* }}} */
416*5697Smcpowers 
417*5697Smcpowers /*------------------------------------------------------------------------*/
418*5697Smcpowers /* {{{ Digit arithmetic */
419*5697Smcpowers 
420*5697Smcpowers /* {{{ mp_add_d(a, d, b) */
421*5697Smcpowers 
422*5697Smcpowers /*
423*5697Smcpowers   mp_add_d(a, d, b)
424*5697Smcpowers 
425*5697Smcpowers   Compute the sum b = a + d, for a single digit d.  Respects the sign of
426*5697Smcpowers   its primary addend (single digits are unsigned anyway).
427*5697Smcpowers  */
428*5697Smcpowers 
429*5697Smcpowers mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b)
430*5697Smcpowers {
431*5697Smcpowers   mp_int   tmp;
432*5697Smcpowers   mp_err   res;
433*5697Smcpowers 
434*5697Smcpowers   ARGCHK(a != NULL && b != NULL, MP_BADARG);
435*5697Smcpowers 
436*5697Smcpowers   if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
437*5697Smcpowers     return res;
438*5697Smcpowers 
439*5697Smcpowers   if(SIGN(&tmp) == ZPOS) {
440*5697Smcpowers     if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
441*5697Smcpowers       goto CLEANUP;
442*5697Smcpowers   } else if(s_mp_cmp_d(&tmp, d) >= 0) {
443*5697Smcpowers     if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
444*5697Smcpowers       goto CLEANUP;
445*5697Smcpowers   } else {
446*5697Smcpowers     mp_neg(&tmp, &tmp);
447*5697Smcpowers 
448*5697Smcpowers     DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
449*5697Smcpowers   }
450*5697Smcpowers 
451*5697Smcpowers   if(s_mp_cmp_d(&tmp, 0) == 0)
452*5697Smcpowers     SIGN(&tmp) = ZPOS;
453*5697Smcpowers 
454*5697Smcpowers   s_mp_exch(&tmp, b);
455*5697Smcpowers 
456*5697Smcpowers CLEANUP:
457*5697Smcpowers   mp_clear(&tmp);
458*5697Smcpowers   return res;
459*5697Smcpowers 
460*5697Smcpowers } /* end mp_add_d() */
461*5697Smcpowers 
462*5697Smcpowers /* }}} */
463*5697Smcpowers 
464*5697Smcpowers /* {{{ mp_sub_d(a, d, b) */
465*5697Smcpowers 
466*5697Smcpowers /*
467*5697Smcpowers   mp_sub_d(a, d, b)
468*5697Smcpowers 
469*5697Smcpowers   Compute the difference b = a - d, for a single digit d.  Respects the
470*5697Smcpowers   sign of its subtrahend (single digits are unsigned anyway).
471*5697Smcpowers  */
472*5697Smcpowers 
473*5697Smcpowers mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b)
474*5697Smcpowers {
475*5697Smcpowers   mp_int   tmp;
476*5697Smcpowers   mp_err   res;
477*5697Smcpowers 
478*5697Smcpowers   ARGCHK(a != NULL && b != NULL, MP_BADARG);
479*5697Smcpowers 
480*5697Smcpowers   if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
481*5697Smcpowers     return res;
482*5697Smcpowers 
483*5697Smcpowers   if(SIGN(&tmp) == NEG) {
484*5697Smcpowers     if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)
485*5697Smcpowers       goto CLEANUP;
486*5697Smcpowers   } else if(s_mp_cmp_d(&tmp, d) >= 0) {
487*5697Smcpowers     if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)
488*5697Smcpowers       goto CLEANUP;
489*5697Smcpowers   } else {
490*5697Smcpowers     mp_neg(&tmp, &tmp);
491*5697Smcpowers 
492*5697Smcpowers     DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);
493*5697Smcpowers     SIGN(&tmp) = NEG;
494*5697Smcpowers   }
495*5697Smcpowers 
496*5697Smcpowers   if(s_mp_cmp_d(&tmp, 0) == 0)
497*5697Smcpowers     SIGN(&tmp) = ZPOS;
498*5697Smcpowers 
499*5697Smcpowers   s_mp_exch(&tmp, b);
500*5697Smcpowers 
501*5697Smcpowers CLEANUP:
502*5697Smcpowers   mp_clear(&tmp);
503*5697Smcpowers   return res;
504*5697Smcpowers 
505*5697Smcpowers } /* end mp_sub_d() */
506*5697Smcpowers 
507*5697Smcpowers /* }}} */
508*5697Smcpowers 
509*5697Smcpowers /* {{{ mp_mul_d(a, d, b) */
510*5697Smcpowers 
511*5697Smcpowers /*
512*5697Smcpowers   mp_mul_d(a, d, b)
513*5697Smcpowers 
514*5697Smcpowers   Compute the product b = a * d, for a single digit d.  Respects the sign
515*5697Smcpowers   of its multiplicand (single digits are unsigned anyway)
516*5697Smcpowers  */
517*5697Smcpowers 
518*5697Smcpowers mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b)
519*5697Smcpowers {
520*5697Smcpowers   mp_err  res;
521*5697Smcpowers 
522*5697Smcpowers   ARGCHK(a != NULL && b != NULL, MP_BADARG);
523*5697Smcpowers 
524*5697Smcpowers   if(d == 0) {
525*5697Smcpowers     mp_zero(b);
526*5697Smcpowers     return MP_OKAY;
527*5697Smcpowers   }
528*5697Smcpowers 
529*5697Smcpowers   if((res = mp_copy(a, b)) != MP_OKAY)
530*5697Smcpowers     return res;
531*5697Smcpowers 
532*5697Smcpowers   res = s_mp_mul_d(b, d);
533*5697Smcpowers 
534*5697Smcpowers   return res;
535*5697Smcpowers 
536*5697Smcpowers } /* end mp_mul_d() */
537*5697Smcpowers 
538*5697Smcpowers /* }}} */
539*5697Smcpowers 
540*5697Smcpowers /* {{{ mp_mul_2(a, c) */
541*5697Smcpowers 
542*5697Smcpowers mp_err mp_mul_2(const mp_int *a, mp_int *c)
543*5697Smcpowers {
544*5697Smcpowers   mp_err  res;
545*5697Smcpowers 
546*5697Smcpowers   ARGCHK(a != NULL && c != NULL, MP_BADARG);
547*5697Smcpowers 
548*5697Smcpowers   if((res = mp_copy(a, c)) != MP_OKAY)
549*5697Smcpowers     return res;
550*5697Smcpowers 
551*5697Smcpowers   return s_mp_mul_2(c);
552*5697Smcpowers 
553*5697Smcpowers } /* end mp_mul_2() */
554*5697Smcpowers 
555*5697Smcpowers /* }}} */
556*5697Smcpowers 
557*5697Smcpowers /* {{{ mp_div_d(a, d, q, r) */
558*5697Smcpowers 
559*5697Smcpowers /*
560*5697Smcpowers   mp_div_d(a, d, q, r)
561*5697Smcpowers 
562*5697Smcpowers   Compute the quotient q = a / d and remainder r = a mod d, for a
563*5697Smcpowers   single digit d.  Respects the sign of its divisor (single digits are
564*5697Smcpowers   unsigned anyway).
565*5697Smcpowers  */
566*5697Smcpowers 
567*5697Smcpowers mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
568*5697Smcpowers {
569*5697Smcpowers   mp_err   res;
570*5697Smcpowers   mp_int   qp;
571*5697Smcpowers   mp_digit rem;
572*5697Smcpowers   int      pow;
573*5697Smcpowers 
574*5697Smcpowers   ARGCHK(a != NULL, MP_BADARG);
575*5697Smcpowers 
576*5697Smcpowers   if(d == 0)
577*5697Smcpowers     return MP_RANGE;
578*5697Smcpowers 
579*5697Smcpowers   /* Shortcut for powers of two ... */
580*5697Smcpowers   if((pow = s_mp_ispow2d(d)) >= 0) {
581*5697Smcpowers     mp_digit  mask;
582*5697Smcpowers 
583*5697Smcpowers     mask = ((mp_digit)1 << pow) - 1;
584*5697Smcpowers     rem = DIGIT(a, 0) & mask;
585*5697Smcpowers 
586*5697Smcpowers     if(q) {
587*5697Smcpowers       mp_copy(a, q);
588*5697Smcpowers       s_mp_div_2d(q, pow);
589*5697Smcpowers     }
590*5697Smcpowers 
591*5697Smcpowers     if(r)
592*5697Smcpowers       *r = rem;
593*5697Smcpowers 
594*5697Smcpowers     return MP_OKAY;
595*5697Smcpowers   }
596*5697Smcpowers 
597*5697Smcpowers   if((res = mp_init_copy(&qp, a)) != MP_OKAY)
598*5697Smcpowers     return res;
599*5697Smcpowers 
600*5697Smcpowers   res = s_mp_div_d(&qp, d, &rem);
601*5697Smcpowers 
602*5697Smcpowers   if(s_mp_cmp_d(&qp, 0) == 0)
603*5697Smcpowers     SIGN(q) = ZPOS;
604*5697Smcpowers 
605*5697Smcpowers   if(r)
606*5697Smcpowers     *r = rem;
607*5697Smcpowers 
608*5697Smcpowers   if(q)
609*5697Smcpowers     s_mp_exch(&qp, q);
610*5697Smcpowers 
611*5697Smcpowers   mp_clear(&qp);
612*5697Smcpowers   return res;
613*5697Smcpowers 
614*5697Smcpowers } /* end mp_div_d() */
615*5697Smcpowers 
616*5697Smcpowers /* }}} */
617*5697Smcpowers 
618*5697Smcpowers /* {{{ mp_div_2(a, c) */
619*5697Smcpowers 
620*5697Smcpowers /*
621*5697Smcpowers   mp_div_2(a, c)
622*5697Smcpowers 
623*5697Smcpowers   Compute c = a / 2, disregarding the remainder.
624*5697Smcpowers  */
625*5697Smcpowers 
626*5697Smcpowers mp_err mp_div_2(const mp_int *a, mp_int *c)
627*5697Smcpowers {
628*5697Smcpowers   mp_err  res;
629*5697Smcpowers 
630*5697Smcpowers   ARGCHK(a != NULL && c != NULL, MP_BADARG);
631*5697Smcpowers 
632*5697Smcpowers   if((res = mp_copy(a, c)) != MP_OKAY)
633*5697Smcpowers     return res;
634*5697Smcpowers 
635*5697Smcpowers   s_mp_div_2(c);
636*5697Smcpowers 
637*5697Smcpowers   return MP_OKAY;
638*5697Smcpowers 
639*5697Smcpowers } /* end mp_div_2() */
640*5697Smcpowers 
641*5697Smcpowers /* }}} */
642*5697Smcpowers 
643*5697Smcpowers /* {{{ mp_expt_d(a, d, b) */
644*5697Smcpowers 
645*5697Smcpowers mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c)
646*5697Smcpowers {
647*5697Smcpowers   mp_int   s, x;
648*5697Smcpowers   mp_err   res;
649*5697Smcpowers 
650*5697Smcpowers   ARGCHK(a != NULL && c != NULL, MP_BADARG);
651*5697Smcpowers 
652*5697Smcpowers   if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
653*5697Smcpowers     return res;
654*5697Smcpowers   if((res = mp_init_copy(&x, a)) != MP_OKAY)
655*5697Smcpowers     goto X;
656*5697Smcpowers 
657*5697Smcpowers   DIGIT(&s, 0) = 1;
658*5697Smcpowers 
659*5697Smcpowers   while(d != 0) {
660*5697Smcpowers     if(d & 1) {
661*5697Smcpowers       if((res = s_mp_mul(&s, &x)) != MP_OKAY)
662*5697Smcpowers 	goto CLEANUP;
663*5697Smcpowers     }
664*5697Smcpowers 
665*5697Smcpowers     d /= 2;
666*5697Smcpowers 
667*5697Smcpowers     if((res = s_mp_sqr(&x)) != MP_OKAY)
668*5697Smcpowers       goto CLEANUP;
669*5697Smcpowers   }
670*5697Smcpowers 
671*5697Smcpowers   s_mp_exch(&s, c);
672*5697Smcpowers 
673*5697Smcpowers CLEANUP:
674*5697Smcpowers   mp_clear(&x);
675*5697Smcpowers X:
676*5697Smcpowers   mp_clear(&s);
677*5697Smcpowers 
678*5697Smcpowers   return res;
679*5697Smcpowers 
680*5697Smcpowers } /* end mp_expt_d() */
681*5697Smcpowers 
682*5697Smcpowers /* }}} */
683*5697Smcpowers 
684*5697Smcpowers /* }}} */
685*5697Smcpowers 
686*5697Smcpowers /*------------------------------------------------------------------------*/
687*5697Smcpowers /* {{{ Full arithmetic */
688*5697Smcpowers 
689*5697Smcpowers /* {{{ mp_abs(a, b) */
690*5697Smcpowers 
691*5697Smcpowers /*
692*5697Smcpowers   mp_abs(a, b)
693*5697Smcpowers 
694*5697Smcpowers   Compute b = |a|.  'a' and 'b' may be identical.
695*5697Smcpowers  */
696*5697Smcpowers 
697*5697Smcpowers mp_err mp_abs(const mp_int *a, mp_int *b)
698*5697Smcpowers {
699*5697Smcpowers   mp_err   res;
700*5697Smcpowers 
701*5697Smcpowers   ARGCHK(a != NULL && b != NULL, MP_BADARG);
702*5697Smcpowers 
703*5697Smcpowers   if((res = mp_copy(a, b)) != MP_OKAY)
704*5697Smcpowers     return res;
705*5697Smcpowers 
706*5697Smcpowers   SIGN(b) = ZPOS;
707*5697Smcpowers 
708*5697Smcpowers   return MP_OKAY;
709*5697Smcpowers 
710*5697Smcpowers } /* end mp_abs() */
711*5697Smcpowers 
712*5697Smcpowers /* }}} */
713*5697Smcpowers 
714*5697Smcpowers /* {{{ mp_neg(a, b) */
715*5697Smcpowers 
716*5697Smcpowers /*
717*5697Smcpowers   mp_neg(a, b)
718*5697Smcpowers 
719*5697Smcpowers   Compute b = -a.  'a' and 'b' may be identical.
720*5697Smcpowers  */
721*5697Smcpowers 
722*5697Smcpowers mp_err mp_neg(const mp_int *a, mp_int *b)
723*5697Smcpowers {
724*5697Smcpowers   mp_err   res;
725*5697Smcpowers 
726*5697Smcpowers   ARGCHK(a != NULL && b != NULL, MP_BADARG);
727*5697Smcpowers 
728*5697Smcpowers   if((res = mp_copy(a, b)) != MP_OKAY)
729*5697Smcpowers     return res;
730*5697Smcpowers 
731*5697Smcpowers   if(s_mp_cmp_d(b, 0) == MP_EQ)
732*5697Smcpowers     SIGN(b) = ZPOS;
733*5697Smcpowers   else
734*5697Smcpowers     SIGN(b) = (SIGN(b) == NEG) ? ZPOS : NEG;
735*5697Smcpowers 
736*5697Smcpowers   return MP_OKAY;
737*5697Smcpowers 
738*5697Smcpowers } /* end mp_neg() */
739*5697Smcpowers 
740*5697Smcpowers /* }}} */
741*5697Smcpowers 
742*5697Smcpowers /* {{{ mp_add(a, b, c) */
743*5697Smcpowers 
744*5697Smcpowers /*
745*5697Smcpowers   mp_add(a, b, c)
746*5697Smcpowers 
747*5697Smcpowers   Compute c = a + b.  All parameters may be identical.
748*5697Smcpowers  */
749*5697Smcpowers 
750*5697Smcpowers mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c)
751*5697Smcpowers {
752*5697Smcpowers   mp_err  res;
753*5697Smcpowers 
754*5697Smcpowers   ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
755*5697Smcpowers 
756*5697Smcpowers   if(SIGN(a) == SIGN(b)) { /* same sign:  add values, keep sign */
757*5697Smcpowers     MP_CHECKOK( s_mp_add_3arg(a, b, c) );
758*5697Smcpowers   } else if(s_mp_cmp(a, b) >= 0) {  /* different sign: |a| >= |b|   */
759*5697Smcpowers     MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
760*5697Smcpowers   } else {                          /* different sign: |a|  < |b|   */
761*5697Smcpowers     MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
762*5697Smcpowers   }
763*5697Smcpowers 
764*5697Smcpowers   if (s_mp_cmp_d(c, 0) == MP_EQ)
765*5697Smcpowers     SIGN(c) = ZPOS;
766*5697Smcpowers 
767*5697Smcpowers CLEANUP:
768*5697Smcpowers   return res;
769*5697Smcpowers 
770*5697Smcpowers } /* end mp_add() */
771*5697Smcpowers 
772*5697Smcpowers /* }}} */
773*5697Smcpowers 
774*5697Smcpowers /* {{{ mp_sub(a, b, c) */
775*5697Smcpowers 
776*5697Smcpowers /*
777*5697Smcpowers   mp_sub(a, b, c)
778*5697Smcpowers 
779*5697Smcpowers   Compute c = a - b.  All parameters may be identical.
780*5697Smcpowers  */
781*5697Smcpowers 
782*5697Smcpowers mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
783*5697Smcpowers {
784*5697Smcpowers   mp_err  res;
785*5697Smcpowers   int     magDiff;
786*5697Smcpowers 
787*5697Smcpowers   ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
788*5697Smcpowers 
789*5697Smcpowers   if (a == b) {
790*5697Smcpowers     mp_zero(c);
791*5697Smcpowers     return MP_OKAY;
792*5697Smcpowers   }
793*5697Smcpowers 
794*5697Smcpowers   if (MP_SIGN(a) != MP_SIGN(b)) {
795*5697Smcpowers     MP_CHECKOK( s_mp_add_3arg(a, b, c) );
796*5697Smcpowers   } else if (!(magDiff = s_mp_cmp(a, b))) {
797*5697Smcpowers     mp_zero(c);
798*5697Smcpowers     res = MP_OKAY;
799*5697Smcpowers   } else if (magDiff > 0) {
800*5697Smcpowers     MP_CHECKOK( s_mp_sub_3arg(a, b, c) );
801*5697Smcpowers   } else {
802*5697Smcpowers     MP_CHECKOK( s_mp_sub_3arg(b, a, c) );
803*5697Smcpowers     MP_SIGN(c) = !MP_SIGN(a);
804*5697Smcpowers   }
805*5697Smcpowers 
806*5697Smcpowers   if (s_mp_cmp_d(c, 0) == MP_EQ)
807*5697Smcpowers     MP_SIGN(c) = MP_ZPOS;
808*5697Smcpowers 
809*5697Smcpowers CLEANUP:
810*5697Smcpowers   return res;
811*5697Smcpowers 
812*5697Smcpowers } /* end mp_sub() */
813*5697Smcpowers 
814*5697Smcpowers /* }}} */
815*5697Smcpowers 
816*5697Smcpowers /* {{{ mp_mul(a, b, c) */
817*5697Smcpowers 
818*5697Smcpowers /*
819*5697Smcpowers   mp_mul(a, b, c)
820*5697Smcpowers 
821*5697Smcpowers   Compute c = a * b.  All parameters may be identical.
822*5697Smcpowers  */
823*5697Smcpowers mp_err   mp_mul(const mp_int *a, const mp_int *b, mp_int * c)
824*5697Smcpowers {
825*5697Smcpowers   mp_digit *pb;
826*5697Smcpowers   mp_int   tmp;
827*5697Smcpowers   mp_err   res;
828*5697Smcpowers   mp_size  ib;
829*5697Smcpowers   mp_size  useda, usedb;
830*5697Smcpowers 
831*5697Smcpowers   ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
832*5697Smcpowers 
833*5697Smcpowers   if (a == c) {
834*5697Smcpowers     if ((res = mp_init_copy(&tmp, a)) != MP_OKAY)
835*5697Smcpowers       return res;
836*5697Smcpowers     if (a == b)
837*5697Smcpowers       b = &tmp;
838*5697Smcpowers     a = &tmp;
839*5697Smcpowers   } else if (b == c) {
840*5697Smcpowers     if ((res = mp_init_copy(&tmp, b)) != MP_OKAY)
841*5697Smcpowers       return res;
842*5697Smcpowers     b = &tmp;
843*5697Smcpowers   } else {
844*5697Smcpowers     MP_DIGITS(&tmp) = 0;
845*5697Smcpowers   }
846*5697Smcpowers 
847*5697Smcpowers   if (MP_USED(a) < MP_USED(b)) {
848*5697Smcpowers     const mp_int *xch = b;	/* switch a and b, to do fewer outer loops */
849*5697Smcpowers     b = a;
850*5697Smcpowers     a = xch;
851*5697Smcpowers   }
852*5697Smcpowers 
853*5697Smcpowers   MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;
854*5697Smcpowers   if((res = s_mp_pad(c, USED(a) + USED(b))) != MP_OKAY)
855*5697Smcpowers     goto CLEANUP;
856*5697Smcpowers 
857*5697Smcpowers #ifdef NSS_USE_COMBA
858*5697Smcpowers   if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) {
859*5697Smcpowers       if (MP_USED(a) == 4) {
860*5697Smcpowers           s_mp_mul_comba_4(a, b, c);
861*5697Smcpowers           goto CLEANUP;
862*5697Smcpowers       }
863*5697Smcpowers       if (MP_USED(a) == 8) {
864*5697Smcpowers           s_mp_mul_comba_8(a, b, c);
865*5697Smcpowers           goto CLEANUP;
866*5697Smcpowers       }
867*5697Smcpowers       if (MP_USED(a) == 16) {
868*5697Smcpowers           s_mp_mul_comba_16(a, b, c);
869*5697Smcpowers           goto CLEANUP;
870*5697Smcpowers       }
871*5697Smcpowers       if (MP_USED(a) == 32) {
872*5697Smcpowers           s_mp_mul_comba_32(a, b, c);
873*5697Smcpowers           goto CLEANUP;
874*5697Smcpowers       }
875*5697Smcpowers   }
876*5697Smcpowers #endif
877*5697Smcpowers 
878*5697Smcpowers   pb = MP_DIGITS(b);
879*5697Smcpowers   s_mpv_mul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));
880*5697Smcpowers 
881*5697Smcpowers   /* Outer loop:  Digits of b */
882*5697Smcpowers   useda = MP_USED(a);
883*5697Smcpowers   usedb = MP_USED(b);
884*5697Smcpowers   for (ib = 1; ib < usedb; ib++) {
885*5697Smcpowers     mp_digit b_i    = *pb++;
886*5697Smcpowers 
887*5697Smcpowers     /* Inner product:  Digits of a */
888*5697Smcpowers     if (b_i)
889*5697Smcpowers       s_mpv_mul_d_add(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);
890*5697Smcpowers     else
891*5697Smcpowers       MP_DIGIT(c, ib + useda) = b_i;
892*5697Smcpowers   }
893*5697Smcpowers 
894*5697Smcpowers   s_mp_clamp(c);
895*5697Smcpowers 
896*5697Smcpowers   if(SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ)
897*5697Smcpowers     SIGN(c) = ZPOS;
898*5697Smcpowers   else
899*5697Smcpowers     SIGN(c) = NEG;
900*5697Smcpowers 
901*5697Smcpowers CLEANUP:
902*5697Smcpowers   mp_clear(&tmp);
903*5697Smcpowers   return res;
904*5697Smcpowers } /* end mp_mul() */
905*5697Smcpowers 
906*5697Smcpowers /* }}} */
907*5697Smcpowers 
908*5697Smcpowers /* {{{ mp_sqr(a, sqr) */
909*5697Smcpowers 
910*5697Smcpowers #if MP_SQUARE
911*5697Smcpowers /*
912*5697Smcpowers   Computes the square of a.  This can be done more
913*5697Smcpowers   efficiently than a general multiplication, because many of the
914*5697Smcpowers   computation steps are redundant when squaring.  The inner product
915*5697Smcpowers   step is a bit more complicated, but we save a fair number of
916*5697Smcpowers   iterations of the multiplication loop.
917*5697Smcpowers  */
918*5697Smcpowers 
919*5697Smcpowers /* sqr = a^2;   Caller provides both a and tmp; */
920*5697Smcpowers mp_err   mp_sqr(const mp_int *a, mp_int *sqr)
921*5697Smcpowers {
922*5697Smcpowers   mp_digit *pa;
923*5697Smcpowers   mp_digit d;
924*5697Smcpowers   mp_err   res;
925*5697Smcpowers   mp_size  ix;
926*5697Smcpowers   mp_int   tmp;
927*5697Smcpowers   int      count;
928*5697Smcpowers 
929*5697Smcpowers   ARGCHK(a != NULL && sqr != NULL, MP_BADARG);
930*5697Smcpowers 
931*5697Smcpowers   if (a == sqr) {
932*5697Smcpowers     if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
933*5697Smcpowers       return res;
934*5697Smcpowers     a = &tmp;
935*5697Smcpowers   } else {
936*5697Smcpowers     DIGITS(&tmp) = 0;
937*5697Smcpowers     res = MP_OKAY;
938*5697Smcpowers   }
939*5697Smcpowers 
940*5697Smcpowers   ix = 2 * MP_USED(a);
941*5697Smcpowers   if (ix > MP_ALLOC(sqr)) {
942*5697Smcpowers     MP_USED(sqr) = 1;
943*5697Smcpowers     MP_CHECKOK( s_mp_grow(sqr, ix) );
944*5697Smcpowers   }
945*5697Smcpowers   MP_USED(sqr) = ix;
946*5697Smcpowers   MP_DIGIT(sqr, 0) = 0;
947*5697Smcpowers 
948*5697Smcpowers #ifdef NSS_USE_COMBA
949*5697Smcpowers   if (IS_POWER_OF_2(MP_USED(a))) {
950*5697Smcpowers       if (MP_USED(a) == 4) {
951*5697Smcpowers           s_mp_sqr_comba_4(a, sqr);
952*5697Smcpowers           goto CLEANUP;
953*5697Smcpowers       }
954*5697Smcpowers       if (MP_USED(a) == 8) {
955*5697Smcpowers           s_mp_sqr_comba_8(a, sqr);
956*5697Smcpowers           goto CLEANUP;
957*5697Smcpowers       }
958*5697Smcpowers       if (MP_USED(a) == 16) {
959*5697Smcpowers           s_mp_sqr_comba_16(a, sqr);
960*5697Smcpowers           goto CLEANUP;
961*5697Smcpowers       }
962*5697Smcpowers       if (MP_USED(a) == 32) {
963*5697Smcpowers           s_mp_sqr_comba_32(a, sqr);
964*5697Smcpowers           goto CLEANUP;
965*5697Smcpowers       }
966*5697Smcpowers   }
967*5697Smcpowers #endif
968*5697Smcpowers 
969*5697Smcpowers   pa = MP_DIGITS(a);
970*5697Smcpowers   count = MP_USED(a) - 1;
971*5697Smcpowers   if (count > 0) {
972*5697Smcpowers     d = *pa++;
973*5697Smcpowers     s_mpv_mul_d(pa, count, d, MP_DIGITS(sqr) + 1);
974*5697Smcpowers     for (ix = 3; --count > 0; ix += 2) {
975*5697Smcpowers       d = *pa++;
976*5697Smcpowers       s_mpv_mul_d_add(pa, count, d, MP_DIGITS(sqr) + ix);
977*5697Smcpowers     } /* for(ix ...) */
978*5697Smcpowers     MP_DIGIT(sqr, MP_USED(sqr)-1) = 0; /* above loop stopped short of this. */
979*5697Smcpowers 
980*5697Smcpowers     /* now sqr *= 2 */
981*5697Smcpowers     s_mp_mul_2(sqr);
982*5697Smcpowers   } else {
983*5697Smcpowers     MP_DIGIT(sqr, 1) = 0;
984*5697Smcpowers   }
985*5697Smcpowers 
986*5697Smcpowers   /* now add the squares of the digits of a to sqr. */
987*5697Smcpowers   s_mpv_sqr_add_prop(MP_DIGITS(a), MP_USED(a), MP_DIGITS(sqr));
988*5697Smcpowers 
989*5697Smcpowers   SIGN(sqr) = ZPOS;
990*5697Smcpowers   s_mp_clamp(sqr);
991*5697Smcpowers 
992*5697Smcpowers CLEANUP:
993*5697Smcpowers   mp_clear(&tmp);
994*5697Smcpowers   return res;
995*5697Smcpowers 
996*5697Smcpowers } /* end mp_sqr() */
997*5697Smcpowers #endif
998*5697Smcpowers 
999*5697Smcpowers /* }}} */
1000*5697Smcpowers 
1001*5697Smcpowers /* {{{ mp_div(a, b, q, r) */
1002*5697Smcpowers 
1003*5697Smcpowers /*
1004*5697Smcpowers   mp_div(a, b, q, r)
1005*5697Smcpowers 
1006*5697Smcpowers   Compute q = a / b and r = a mod b.  Input parameters may be re-used
1007*5697Smcpowers   as output parameters.  If q or r is NULL, that portion of the
1008*5697Smcpowers   computation will be discarded (although it will still be computed)
1009*5697Smcpowers  */
1010*5697Smcpowers mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r)
1011*5697Smcpowers {
1012*5697Smcpowers   mp_err   res;
1013*5697Smcpowers   mp_int   *pQ, *pR;
1014*5697Smcpowers   mp_int   qtmp, rtmp, btmp;
1015*5697Smcpowers   int      cmp;
1016*5697Smcpowers   mp_sign  signA;
1017*5697Smcpowers   mp_sign  signB;
1018*5697Smcpowers 
1019*5697Smcpowers   ARGCHK(a != NULL && b != NULL, MP_BADARG);
1020*5697Smcpowers 
1021*5697Smcpowers   signA = MP_SIGN(a);
1022*5697Smcpowers   signB = MP_SIGN(b);
1023*5697Smcpowers 
1024*5697Smcpowers   if(mp_cmp_z(b) == MP_EQ)
1025*5697Smcpowers     return MP_RANGE;
1026*5697Smcpowers 
1027*5697Smcpowers   DIGITS(&qtmp) = 0;
1028*5697Smcpowers   DIGITS(&rtmp) = 0;
1029*5697Smcpowers   DIGITS(&btmp) = 0;
1030*5697Smcpowers 
1031*5697Smcpowers   /* Set up some temporaries... */
1032*5697Smcpowers   if (!r || r == a || r == b) {
1033*5697Smcpowers     MP_CHECKOK( mp_init_copy(&rtmp, a) );
1034*5697Smcpowers     pR = &rtmp;
1035*5697Smcpowers   } else {
1036*5697Smcpowers     MP_CHECKOK( mp_copy(a, r) );
1037*5697Smcpowers     pR = r;
1038*5697Smcpowers   }
1039*5697Smcpowers 
1040*5697Smcpowers   if (!q || q == a || q == b) {
1041*5697Smcpowers     MP_CHECKOK( mp_init_size(&qtmp, MP_USED(a), FLAG(a)) );
1042*5697Smcpowers     pQ = &qtmp;
1043*5697Smcpowers   } else {
1044*5697Smcpowers     MP_CHECKOK( s_mp_pad(q, MP_USED(a)) );
1045*5697Smcpowers     pQ = q;
1046*5697Smcpowers     mp_zero(pQ);
1047*5697Smcpowers   }
1048*5697Smcpowers 
1049*5697Smcpowers   /*
1050*5697Smcpowers     If |a| <= |b|, we can compute the solution without division;
1051*5697Smcpowers     otherwise, we actually do the work required.
1052*5697Smcpowers    */
1053*5697Smcpowers   if ((cmp = s_mp_cmp(a, b)) <= 0) {
1054*5697Smcpowers     if (cmp) {
1055*5697Smcpowers       /* r was set to a above. */
1056*5697Smcpowers       mp_zero(pQ);
1057*5697Smcpowers     } else {
1058*5697Smcpowers       mp_set(pQ, 1);
1059*5697Smcpowers       mp_zero(pR);
1060*5697Smcpowers     }
1061*5697Smcpowers   } else {
1062*5697Smcpowers     MP_CHECKOK( mp_init_copy(&btmp, b) );
1063*5697Smcpowers     MP_CHECKOK( s_mp_div(pR, &btmp, pQ) );
1064*5697Smcpowers   }
1065*5697Smcpowers 
1066*5697Smcpowers   /* Compute the signs for the output  */
1067*5697Smcpowers   MP_SIGN(pR) = signA;   /* Sr = Sa              */
1068*5697Smcpowers   /* Sq = ZPOS if Sa == Sb */ /* Sq = NEG if Sa != Sb */
1069*5697Smcpowers   MP_SIGN(pQ) = (signA == signB) ? ZPOS : NEG;
1070*5697Smcpowers 
1071*5697Smcpowers   if(s_mp_cmp_d(pQ, 0) == MP_EQ)
1072*5697Smcpowers     SIGN(pQ) = ZPOS;
1073*5697Smcpowers   if(s_mp_cmp_d(pR, 0) == MP_EQ)
1074*5697Smcpowers     SIGN(pR) = ZPOS;
1075*5697Smcpowers 
1076*5697Smcpowers   /* Copy output, if it is needed      */
1077*5697Smcpowers   if(q && q != pQ)
1078*5697Smcpowers     s_mp_exch(pQ, q);
1079*5697Smcpowers 
1080*5697Smcpowers   if(r && r != pR)
1081*5697Smcpowers     s_mp_exch(pR, r);
1082*5697Smcpowers 
1083*5697Smcpowers CLEANUP:
1084*5697Smcpowers   mp_clear(&btmp);
1085*5697Smcpowers   mp_clear(&rtmp);
1086*5697Smcpowers   mp_clear(&qtmp);
1087*5697Smcpowers 
1088*5697Smcpowers   return res;
1089*5697Smcpowers 
1090*5697Smcpowers } /* end mp_div() */
1091*5697Smcpowers 
1092*5697Smcpowers /* }}} */
1093*5697Smcpowers 
1094*5697Smcpowers /* {{{ mp_div_2d(a, d, q, r) */
1095*5697Smcpowers 
1096*5697Smcpowers mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r)
1097*5697Smcpowers {
1098*5697Smcpowers   mp_err  res;
1099*5697Smcpowers 
1100*5697Smcpowers   ARGCHK(a != NULL, MP_BADARG);
1101*5697Smcpowers 
1102*5697Smcpowers   if(q) {
1103*5697Smcpowers     if((res = mp_copy(a, q)) != MP_OKAY)
1104*5697Smcpowers       return res;
1105*5697Smcpowers   }
1106*5697Smcpowers   if(r) {
1107*5697Smcpowers     if((res = mp_copy(a, r)) != MP_OKAY)
1108*5697Smcpowers       return res;
1109*5697Smcpowers   }
1110*5697Smcpowers   if(q) {
1111*5697Smcpowers     s_mp_div_2d(q, d);
1112*5697Smcpowers   }
1113*5697Smcpowers   if(r) {
1114*5697Smcpowers     s_mp_mod_2d(r, d);
1115*5697Smcpowers   }
1116*5697Smcpowers 
1117*5697Smcpowers   return MP_OKAY;
1118*5697Smcpowers 
1119*5697Smcpowers } /* end mp_div_2d() */
1120*5697Smcpowers 
1121*5697Smcpowers /* }}} */
1122*5697Smcpowers 
1123*5697Smcpowers /* {{{ mp_expt(a, b, c) */
1124*5697Smcpowers 
1125*5697Smcpowers /*
1126*5697Smcpowers   mp_expt(a, b, c)
1127*5697Smcpowers 
1128*5697Smcpowers   Compute c = a ** b, that is, raise a to the b power.  Uses a
1129*5697Smcpowers   standard iterative square-and-multiply technique.
1130*5697Smcpowers  */
1131*5697Smcpowers 
1132*5697Smcpowers mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
1133*5697Smcpowers {
1134*5697Smcpowers   mp_int   s, x;
1135*5697Smcpowers   mp_err   res;
1136*5697Smcpowers   mp_digit d;
1137*5697Smcpowers   int      dig, bit;
1138*5697Smcpowers 
1139*5697Smcpowers   ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
1140*5697Smcpowers 
1141*5697Smcpowers   if(mp_cmp_z(b) < 0)
1142*5697Smcpowers     return MP_RANGE;
1143*5697Smcpowers 
1144*5697Smcpowers   if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
1145*5697Smcpowers     return res;
1146*5697Smcpowers 
1147*5697Smcpowers   mp_set(&s, 1);
1148*5697Smcpowers 
1149*5697Smcpowers   if((res = mp_init_copy(&x, a)) != MP_OKAY)
1150*5697Smcpowers     goto X;
1151*5697Smcpowers 
1152*5697Smcpowers   /* Loop over low-order digits in ascending order */
1153*5697Smcpowers   for(dig = 0; dig < (USED(b) - 1); dig++) {
1154*5697Smcpowers     d = DIGIT(b, dig);
1155*5697Smcpowers 
1156*5697Smcpowers     /* Loop over bits of each non-maximal digit */
1157*5697Smcpowers     for(bit = 0; bit < DIGIT_BIT; bit++) {
1158*5697Smcpowers       if(d & 1) {
1159*5697Smcpowers 	if((res = s_mp_mul(&s, &x)) != MP_OKAY)
1160*5697Smcpowers 	  goto CLEANUP;
1161*5697Smcpowers       }
1162*5697Smcpowers 
1163*5697Smcpowers       d >>= 1;
1164*5697Smcpowers 
1165*5697Smcpowers       if((res = s_mp_sqr(&x)) != MP_OKAY)
1166*5697Smcpowers 	goto CLEANUP;
1167*5697Smcpowers     }
1168*5697Smcpowers   }
1169*5697Smcpowers 
1170*5697Smcpowers   /* Consider now the last digit... */
1171*5697Smcpowers   d = DIGIT(b, dig);
1172*5697Smcpowers 
1173*5697Smcpowers   while(d) {
1174*5697Smcpowers     if(d & 1) {
1175*5697Smcpowers       if((res = s_mp_mul(&s, &x)) != MP_OKAY)
1176*5697Smcpowers 	goto CLEANUP;
1177*5697Smcpowers     }
1178*5697Smcpowers 
1179*5697Smcpowers     d >>= 1;
1180*5697Smcpowers 
1181*5697Smcpowers     if((res = s_mp_sqr(&x)) != MP_OKAY)
1182*5697Smcpowers       goto CLEANUP;
1183*5697Smcpowers   }
1184*5697Smcpowers 
1185*5697Smcpowers   if(mp_iseven(b))
1186*5697Smcpowers     SIGN(&s) = SIGN(a);
1187*5697Smcpowers 
1188*5697Smcpowers   res = mp_copy(&s, c);
1189*5697Smcpowers 
1190*5697Smcpowers CLEANUP:
1191*5697Smcpowers   mp_clear(&x);
1192*5697Smcpowers X:
1193*5697Smcpowers   mp_clear(&s);
1194*5697Smcpowers 
1195*5697Smcpowers   return res;
1196*5697Smcpowers 
1197*5697Smcpowers } /* end mp_expt() */
1198*5697Smcpowers 
1199*5697Smcpowers /* }}} */
1200*5697Smcpowers 
1201*5697Smcpowers /* {{{ mp_2expt(a, k) */
1202*5697Smcpowers 
1203*5697Smcpowers /* Compute a = 2^k */
1204*5697Smcpowers 
1205*5697Smcpowers mp_err mp_2expt(mp_int *a, mp_digit k)
1206*5697Smcpowers {
1207*5697Smcpowers   ARGCHK(a != NULL, MP_BADARG);
1208*5697Smcpowers 
1209*5697Smcpowers   return s_mp_2expt(a, k);
1210*5697Smcpowers 
1211*5697Smcpowers } /* end mp_2expt() */
1212*5697Smcpowers 
1213*5697Smcpowers /* }}} */
1214*5697Smcpowers 
1215*5697Smcpowers /* {{{ mp_mod(a, m, c) */
1216*5697Smcpowers 
1217*5697Smcpowers /*
1218*5697Smcpowers   mp_mod(a, m, c)
1219*5697Smcpowers 
1220*5697Smcpowers   Compute c = a (mod m).  Result will always be 0 <= c < m.
1221*5697Smcpowers  */
1222*5697Smcpowers 
1223*5697Smcpowers mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c)
1224*5697Smcpowers {
1225*5697Smcpowers   mp_err  res;
1226*5697Smcpowers   int     mag;
1227*5697Smcpowers 
1228*5697Smcpowers   ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
1229*5697Smcpowers 
1230*5697Smcpowers   if(SIGN(m) == NEG)
1231*5697Smcpowers     return MP_RANGE;
1232*5697Smcpowers 
1233*5697Smcpowers   /*
1234*5697Smcpowers      If |a| > m, we need to divide to get the remainder and take the
1235*5697Smcpowers      absolute value.
1236*5697Smcpowers 
1237*5697Smcpowers      If |a| < m, we don't need to do any division, just copy and adjust
1238*5697Smcpowers      the sign (if a is negative).
1239*5697Smcpowers 
1240*5697Smcpowers      If |a| == m, we can simply set the result to zero.
1241*5697Smcpowers 
1242*5697Smcpowers      This order is intended to minimize the average path length of the
1243*5697Smcpowers      comparison chain on common workloads -- the most frequent cases are
1244*5697Smcpowers      that |a| != m, so we do those first.
1245*5697Smcpowers    */
1246*5697Smcpowers   if((mag = s_mp_cmp(a, m)) > 0) {
1247*5697Smcpowers     if((res = mp_div(a, m, NULL, c)) != MP_OKAY)
1248*5697Smcpowers       return res;
1249*5697Smcpowers 
1250*5697Smcpowers     if(SIGN(c) == NEG) {
1251*5697Smcpowers       if((res = mp_add(c, m, c)) != MP_OKAY)
1252*5697Smcpowers 	return res;
1253*5697Smcpowers     }
1254*5697Smcpowers 
1255*5697Smcpowers   } else if(mag < 0) {
1256*5697Smcpowers     if((res = mp_copy(a, c)) != MP_OKAY)
1257*5697Smcpowers       return res;
1258*5697Smcpowers 
1259*5697Smcpowers     if(mp_cmp_z(a) < 0) {
1260*5697Smcpowers       if((res = mp_add(c, m, c)) != MP_OKAY)
1261*5697Smcpowers 	return res;
1262*5697Smcpowers 
1263*5697Smcpowers     }
1264*5697Smcpowers 
1265*5697Smcpowers   } else {
1266*5697Smcpowers     mp_zero(c);
1267*5697Smcpowers 
1268*5697Smcpowers   }
1269*5697Smcpowers 
1270*5697Smcpowers   return MP_OKAY;
1271*5697Smcpowers 
1272*5697Smcpowers } /* end mp_mod() */
1273*5697Smcpowers 
1274*5697Smcpowers /* }}} */
1275*5697Smcpowers 
1276*5697Smcpowers /* {{{ mp_mod_d(a, d, c) */
1277*5697Smcpowers 
1278*5697Smcpowers /*
1279*5697Smcpowers   mp_mod_d(a, d, c)
1280*5697Smcpowers 
1281*5697Smcpowers   Compute c = a (mod d).  Result will always be 0 <= c < d
1282*5697Smcpowers  */
1283*5697Smcpowers mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c)
1284*5697Smcpowers {
1285*5697Smcpowers   mp_err   res;
1286*5697Smcpowers   mp_digit rem;
1287*5697Smcpowers 
1288*5697Smcpowers   ARGCHK(a != NULL && c != NULL, MP_BADARG);
1289*5697Smcpowers 
1290*5697Smcpowers   if(s_mp_cmp_d(a, d) > 0) {
1291*5697Smcpowers     if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)
1292*5697Smcpowers       return res;
1293*5697Smcpowers 
1294*5697Smcpowers   } else {
1295*5697Smcpowers     if(SIGN(a) == NEG)
1296*5697Smcpowers       rem = d - DIGIT(a, 0);
1297*5697Smcpowers     else
1298*5697Smcpowers       rem = DIGIT(a, 0);
1299*5697Smcpowers   }
1300*5697Smcpowers 
1301*5697Smcpowers   if(c)
1302*5697Smcpowers     *c = rem;
1303*5697Smcpowers 
1304*5697Smcpowers   return MP_OKAY;
1305*5697Smcpowers 
1306*5697Smcpowers } /* end mp_mod_d() */
1307*5697Smcpowers 
1308*5697Smcpowers /* }}} */
1309*5697Smcpowers 
1310*5697Smcpowers /* {{{ mp_sqrt(a, b) */
1311*5697Smcpowers 
1312*5697Smcpowers /*
1313*5697Smcpowers   mp_sqrt(a, b)
1314*5697Smcpowers 
1315*5697Smcpowers   Compute the integer square root of a, and store the result in b.
1316*5697Smcpowers   Uses an integer-arithmetic version of Newton's iterative linear
1317*5697Smcpowers   approximation technique to determine this value; the result has the
1318*5697Smcpowers   following two properties:
1319*5697Smcpowers 
1320*5697Smcpowers      b^2 <= a
1321*5697Smcpowers      (b+1)^2 >= a
1322*5697Smcpowers 
1323*5697Smcpowers   It is a range error to pass a negative value.
1324*5697Smcpowers  */
1325*5697Smcpowers mp_err mp_sqrt(const mp_int *a, mp_int *b)
1326*5697Smcpowers {
1327*5697Smcpowers   mp_int   x, t;
1328*5697Smcpowers   mp_err   res;
1329*5697Smcpowers   mp_size  used;
1330*5697Smcpowers 
1331*5697Smcpowers   ARGCHK(a != NULL && b != NULL, MP_BADARG);
1332*5697Smcpowers 
1333*5697Smcpowers   /* Cannot take square root of a negative value */
1334*5697Smcpowers   if(SIGN(a) == NEG)
1335*5697Smcpowers     return MP_RANGE;
1336*5697Smcpowers 
1337*5697Smcpowers   /* Special cases for zero and one, trivial     */
1338*5697Smcpowers   if(mp_cmp_d(a, 1) <= 0)
1339*5697Smcpowers     return mp_copy(a, b);
1340*5697Smcpowers 
1341*5697Smcpowers   /* Initialize the temporaries we'll use below  */
1342*5697Smcpowers   if((res = mp_init_size(&t, USED(a), FLAG(a))) != MP_OKAY)
1343*5697Smcpowers     return res;
1344*5697Smcpowers 
1345*5697Smcpowers   /* Compute an initial guess for the iteration as a itself */
1346*5697Smcpowers   if((res = mp_init_copy(&x, a)) != MP_OKAY)
1347*5697Smcpowers     goto X;
1348*5697Smcpowers 
1349*5697Smcpowers   used = MP_USED(&x);
1350*5697Smcpowers   if (used > 1) {
1351*5697Smcpowers     s_mp_rshd(&x, used / 2);
1352*5697Smcpowers   }
1353*5697Smcpowers 
1354*5697Smcpowers   for(;;) {
1355*5697Smcpowers     /* t = (x * x) - a */
1356*5697Smcpowers     mp_copy(&x, &t);      /* can't fail, t is big enough for original x */
1357*5697Smcpowers     if((res = mp_sqr(&t, &t)) != MP_OKAY ||
1358*5697Smcpowers        (res = mp_sub(&t, a, &t)) != MP_OKAY)
1359*5697Smcpowers       goto CLEANUP;
1360*5697Smcpowers 
1361*5697Smcpowers     /* t = t / 2x       */
1362*5697Smcpowers     s_mp_mul_2(&x);
1363*5697Smcpowers     if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
1364*5697Smcpowers       goto CLEANUP;
1365*5697Smcpowers     s_mp_div_2(&x);
1366*5697Smcpowers 
1367*5697Smcpowers     /* Terminate the loop, if the quotient is zero */
1368*5697Smcpowers     if(mp_cmp_z(&t) == MP_EQ)
1369*5697Smcpowers       break;
1370*5697Smcpowers 
1371*5697Smcpowers     /* x = x - t       */
1372*5697Smcpowers     if((res = mp_sub(&x, &t, &x)) != MP_OKAY)
1373*5697Smcpowers       goto CLEANUP;
1374*5697Smcpowers 
1375*5697Smcpowers   }
1376*5697Smcpowers 
1377*5697Smcpowers   /* Copy result to output parameter */
1378*5697Smcpowers   mp_sub_d(&x, 1, &x);
1379*5697Smcpowers   s_mp_exch(&x, b);
1380*5697Smcpowers 
1381*5697Smcpowers  CLEANUP:
1382*5697Smcpowers   mp_clear(&x);
1383*5697Smcpowers  X:
1384*5697Smcpowers   mp_clear(&t);
1385*5697Smcpowers 
1386*5697Smcpowers   return res;
1387*5697Smcpowers 
1388*5697Smcpowers } /* end mp_sqrt() */
1389*5697Smcpowers 
1390*5697Smcpowers /* }}} */
1391*5697Smcpowers 
1392*5697Smcpowers /* }}} */
1393*5697Smcpowers 
1394*5697Smcpowers /*------------------------------------------------------------------------*/
1395*5697Smcpowers /* {{{ Modular arithmetic */
1396*5697Smcpowers 
1397*5697Smcpowers #if MP_MODARITH
1398*5697Smcpowers /* {{{ mp_addmod(a, b, m, c) */
1399*5697Smcpowers 
1400*5697Smcpowers /*
1401*5697Smcpowers   mp_addmod(a, b, m, c)
1402*5697Smcpowers 
1403*5697Smcpowers   Compute c = (a + b) mod m
1404*5697Smcpowers  */
1405*5697Smcpowers 
1406*5697Smcpowers mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
1407*5697Smcpowers {
1408*5697Smcpowers   mp_err  res;
1409*5697Smcpowers 
1410*5697Smcpowers   ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
1411*5697Smcpowers 
1412*5697Smcpowers   if((res = mp_add(a, b, c)) != MP_OKAY)
1413*5697Smcpowers     return res;
1414*5697Smcpowers   if((res = mp_mod(c, m, c)) != MP_OKAY)
1415*5697Smcpowers     return res;
1416*5697Smcpowers 
1417*5697Smcpowers   return MP_OKAY;
1418*5697Smcpowers 
1419*5697Smcpowers }
1420*5697Smcpowers 
1421*5697Smcpowers /* }}} */
1422*5697Smcpowers 
1423*5697Smcpowers /* {{{ mp_submod(a, b, m, c) */
1424*5697Smcpowers 
1425*5697Smcpowers /*
1426*5697Smcpowers   mp_submod(a, b, m, c)
1427*5697Smcpowers 
1428*5697Smcpowers   Compute c = (a - b) mod m
1429*5697Smcpowers  */
1430*5697Smcpowers 
1431*5697Smcpowers mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
1432*5697Smcpowers {
1433*5697Smcpowers   mp_err  res;
1434*5697Smcpowers 
1435*5697Smcpowers   ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
1436*5697Smcpowers 
1437*5697Smcpowers   if((res = mp_sub(a, b, c)) != MP_OKAY)
1438*5697Smcpowers     return res;
1439*5697Smcpowers   if((res = mp_mod(c, m, c)) != MP_OKAY)
1440*5697Smcpowers     return res;
1441*5697Smcpowers 
1442*5697Smcpowers   return MP_OKAY;
1443*5697Smcpowers 
1444*5697Smcpowers }
1445*5697Smcpowers 
1446*5697Smcpowers /* }}} */
1447*5697Smcpowers 
1448*5697Smcpowers /* {{{ mp_mulmod(a, b, m, c) */
1449*5697Smcpowers 
1450*5697Smcpowers /*
1451*5697Smcpowers   mp_mulmod(a, b, m, c)
1452*5697Smcpowers 
1453*5697Smcpowers   Compute c = (a * b) mod m
1454*5697Smcpowers  */
1455*5697Smcpowers 
1456*5697Smcpowers mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
1457*5697Smcpowers {
1458*5697Smcpowers   mp_err  res;
1459*5697Smcpowers 
1460*5697Smcpowers   ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
1461*5697Smcpowers 
1462*5697Smcpowers   if((res = mp_mul(a, b, c)) != MP_OKAY)
1463*5697Smcpowers     return res;
1464*5697Smcpowers   if((res = mp_mod(c, m, c)) != MP_OKAY)
1465*5697Smcpowers     return res;
1466*5697Smcpowers 
1467*5697Smcpowers   return MP_OKAY;
1468*5697Smcpowers 
1469*5697Smcpowers }
1470*5697Smcpowers 
1471*5697Smcpowers /* }}} */
1472*5697Smcpowers 
1473*5697Smcpowers /* {{{ mp_sqrmod(a, m, c) */
1474*5697Smcpowers 
1475*5697Smcpowers #if MP_SQUARE
1476*5697Smcpowers mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c)
1477*5697Smcpowers {
1478*5697Smcpowers   mp_err  res;
1479*5697Smcpowers 
1480*5697Smcpowers   ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
1481*5697Smcpowers 
1482*5697Smcpowers   if((res = mp_sqr(a, c)) != MP_OKAY)
1483*5697Smcpowers     return res;
1484*5697Smcpowers   if((res = mp_mod(c, m, c)) != MP_OKAY)
1485*5697Smcpowers     return res;
1486*5697Smcpowers 
1487*5697Smcpowers   return MP_OKAY;
1488*5697Smcpowers 
1489*5697Smcpowers } /* end mp_sqrmod() */
1490*5697Smcpowers #endif
1491*5697Smcpowers 
1492*5697Smcpowers /* }}} */
1493*5697Smcpowers 
1494*5697Smcpowers /* {{{ s_mp_exptmod(a, b, m, c) */
1495*5697Smcpowers 
1496*5697Smcpowers /*
1497*5697Smcpowers   s_mp_exptmod(a, b, m, c)
1498*5697Smcpowers 
1499*5697Smcpowers   Compute c = (a ** b) mod m.  Uses a standard square-and-multiply
1500*5697Smcpowers   method with modular reductions at each step. (This is basically the
1501*5697Smcpowers   same code as mp_expt(), except for the addition of the reductions)
1502*5697Smcpowers 
1503*5697Smcpowers   The modular reductions are done using Barrett's algorithm (see
1504*5697Smcpowers   s_mp_reduce() below for details)
1505*5697Smcpowers  */
1506*5697Smcpowers 
1507*5697Smcpowers mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)
1508*5697Smcpowers {
1509*5697Smcpowers   mp_int   s, x, mu;
1510*5697Smcpowers   mp_err   res;
1511*5697Smcpowers   mp_digit d;
1512*5697Smcpowers   int      dig, bit;
1513*5697Smcpowers 
1514*5697Smcpowers   ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
1515*5697Smcpowers 
1516*5697Smcpowers   if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
1517*5697Smcpowers     return MP_RANGE;
1518*5697Smcpowers 
1519*5697Smcpowers   if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
1520*5697Smcpowers     return res;
1521*5697Smcpowers   if((res = mp_init_copy(&x, a)) != MP_OKAY ||
1522*5697Smcpowers      (res = mp_mod(&x, m, &x)) != MP_OKAY)
1523*5697Smcpowers     goto X;
1524*5697Smcpowers   if((res = mp_init(&mu, FLAG(a))) != MP_OKAY)
1525*5697Smcpowers     goto MU;
1526*5697Smcpowers 
1527*5697Smcpowers   mp_set(&s, 1);
1528*5697Smcpowers 
1529*5697Smcpowers   /* mu = b^2k / m */
1530*5697Smcpowers   s_mp_add_d(&mu, 1);
1531*5697Smcpowers   s_mp_lshd(&mu, 2 * USED(m));
1532*5697Smcpowers   if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
1533*5697Smcpowers     goto CLEANUP;
1534*5697Smcpowers 
1535*5697Smcpowers   /* Loop over digits of b in ascending order, except highest order */
1536*5697Smcpowers   for(dig = 0; dig < (USED(b) - 1); dig++) {
1537*5697Smcpowers     d = DIGIT(b, dig);
1538*5697Smcpowers 
1539*5697Smcpowers     /* Loop over the bits of the lower-order digits */
1540*5697Smcpowers     for(bit = 0; bit < DIGIT_BIT; bit++) {
1541*5697Smcpowers       if(d & 1) {
1542*5697Smcpowers 	if((res = s_mp_mul(&s, &x)) != MP_OKAY)
1543*5697Smcpowers 	  goto CLEANUP;
1544*5697Smcpowers 	if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
1545*5697Smcpowers 	  goto CLEANUP;
1546*5697Smcpowers       }
1547*5697Smcpowers 
1548*5697Smcpowers       d >>= 1;
1549*5697Smcpowers 
1550*5697Smcpowers       if((res = s_mp_sqr(&x)) != MP_OKAY)
1551*5697Smcpowers 	goto CLEANUP;
1552*5697Smcpowers       if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
1553*5697Smcpowers 	goto CLEANUP;
1554*5697Smcpowers     }
1555*5697Smcpowers   }
1556*5697Smcpowers 
1557*5697Smcpowers   /* Now do the last digit... */
1558*5697Smcpowers   d = DIGIT(b, dig);
1559*5697Smcpowers 
1560*5697Smcpowers   while(d) {
1561*5697Smcpowers     if(d & 1) {
1562*5697Smcpowers       if((res = s_mp_mul(&s, &x)) != MP_OKAY)
1563*5697Smcpowers 	goto CLEANUP;
1564*5697Smcpowers       if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
1565*5697Smcpowers 	goto CLEANUP;
1566*5697Smcpowers     }
1567*5697Smcpowers 
1568*5697Smcpowers     d >>= 1;
1569*5697Smcpowers 
1570*5697Smcpowers     if((res = s_mp_sqr(&x)) != MP_OKAY)
1571*5697Smcpowers       goto CLEANUP;
1572*5697Smcpowers     if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
1573*5697Smcpowers       goto CLEANUP;
1574*5697Smcpowers   }
1575*5697Smcpowers 
1576*5697Smcpowers   s_mp_exch(&s, c);
1577*5697Smcpowers 
1578*5697Smcpowers  CLEANUP:
1579*5697Smcpowers   mp_clear(&mu);
1580*5697Smcpowers  MU:
1581*5697Smcpowers   mp_clear(&x);
1582*5697Smcpowers  X:
1583*5697Smcpowers   mp_clear(&s);
1584*5697Smcpowers 
1585*5697Smcpowers   return res;
1586*5697Smcpowers 
1587*5697Smcpowers } /* end s_mp_exptmod() */
1588*5697Smcpowers 
1589*5697Smcpowers /* }}} */
1590*5697Smcpowers 
1591*5697Smcpowers /* {{{ mp_exptmod_d(a, d, m, c) */
1592*5697Smcpowers 
1593*5697Smcpowers mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c)
1594*5697Smcpowers {
1595*5697Smcpowers   mp_int   s, x;
1596*5697Smcpowers   mp_err   res;
1597*5697Smcpowers 
1598*5697Smcpowers   ARGCHK(a != NULL && c != NULL, MP_BADARG);
1599*5697Smcpowers 
1600*5697Smcpowers   if((res = mp_init(&s, FLAG(a))) != MP_OKAY)
1601*5697Smcpowers     return res;
1602*5697Smcpowers   if((res = mp_init_copy(&x, a)) != MP_OKAY)
1603*5697Smcpowers     goto X;
1604*5697Smcpowers 
1605*5697Smcpowers   mp_set(&s, 1);
1606*5697Smcpowers 
1607*5697Smcpowers   while(d != 0) {
1608*5697Smcpowers     if(d & 1) {
1609*5697Smcpowers       if((res = s_mp_mul(&s, &x)) != MP_OKAY ||
1610*5697Smcpowers 	 (res = mp_mod(&s, m, &s)) != MP_OKAY)
1611*5697Smcpowers 	goto CLEANUP;
1612*5697Smcpowers     }
1613*5697Smcpowers 
1614*5697Smcpowers     d /= 2;
1615*5697Smcpowers 
1616*5697Smcpowers     if((res = s_mp_sqr(&x)) != MP_OKAY ||
1617*5697Smcpowers        (res = mp_mod(&x, m, &x)) != MP_OKAY)
1618*5697Smcpowers       goto CLEANUP;
1619*5697Smcpowers   }
1620*5697Smcpowers 
1621*5697Smcpowers   s_mp_exch(&s, c);
1622*5697Smcpowers 
1623*5697Smcpowers CLEANUP:
1624*5697Smcpowers   mp_clear(&x);
1625*5697Smcpowers X:
1626*5697Smcpowers   mp_clear(&s);
1627*5697Smcpowers 
1628*5697Smcpowers   return res;
1629*5697Smcpowers 
1630*5697Smcpowers } /* end mp_exptmod_d() */
1631*5697Smcpowers 
1632*5697Smcpowers /* }}} */
1633*5697Smcpowers #endif /* if MP_MODARITH */
1634*5697Smcpowers 
1635*5697Smcpowers /* }}} */
1636*5697Smcpowers 
1637*5697Smcpowers /*------------------------------------------------------------------------*/
1638*5697Smcpowers /* {{{ Comparison functions */
1639*5697Smcpowers 
1640*5697Smcpowers /* {{{ mp_cmp_z(a) */
1641*5697Smcpowers 
1642*5697Smcpowers /*
1643*5697Smcpowers   mp_cmp_z(a)
1644*5697Smcpowers 
1645*5697Smcpowers   Compare a <=> 0.  Returns <0 if a<0, 0 if a=0, >0 if a>0.
1646*5697Smcpowers  */
1647*5697Smcpowers 
1648*5697Smcpowers int    mp_cmp_z(const mp_int *a)
1649*5697Smcpowers {
1650*5697Smcpowers   if(SIGN(a) == NEG)
1651*5697Smcpowers     return MP_LT;
1652*5697Smcpowers   else if(USED(a) == 1 && DIGIT(a, 0) == 0)
1653*5697Smcpowers     return MP_EQ;
1654*5697Smcpowers   else
1655*5697Smcpowers     return MP_GT;
1656*5697Smcpowers 
1657*5697Smcpowers } /* end mp_cmp_z() */
1658*5697Smcpowers 
1659*5697Smcpowers /* }}} */
1660*5697Smcpowers 
1661*5697Smcpowers /* {{{ mp_cmp_d(a, d) */
1662*5697Smcpowers 
1663*5697Smcpowers /*
1664*5697Smcpowers   mp_cmp_d(a, d)
1665*5697Smcpowers 
1666*5697Smcpowers   Compare a <=> d.  Returns <0 if a<d, 0 if a=d, >0 if a>d
1667*5697Smcpowers  */
1668*5697Smcpowers 
1669*5697Smcpowers int    mp_cmp_d(const mp_int *a, mp_digit d)
1670*5697Smcpowers {
1671*5697Smcpowers   ARGCHK(a != NULL, MP_EQ);
1672*5697Smcpowers 
1673*5697Smcpowers   if(SIGN(a) == NEG)
1674*5697Smcpowers     return MP_LT;
1675*5697Smcpowers 
1676*5697Smcpowers   return s_mp_cmp_d(a, d);
1677*5697Smcpowers 
1678*5697Smcpowers } /* end mp_cmp_d() */
1679*5697Smcpowers 
1680*5697Smcpowers /* }}} */
1681*5697Smcpowers 
1682*5697Smcpowers /* {{{ mp_cmp(a, b) */
1683*5697Smcpowers 
1684*5697Smcpowers int    mp_cmp(const mp_int *a, const mp_int *b)
1685*5697Smcpowers {
1686*5697Smcpowers   ARGCHK(a != NULL && b != NULL, MP_EQ);
1687*5697Smcpowers 
1688*5697Smcpowers   if(SIGN(a) == SIGN(b)) {
1689*5697Smcpowers     int  mag;
1690*5697Smcpowers 
1691*5697Smcpowers     if((mag = s_mp_cmp(a, b)) == MP_EQ)
1692*5697Smcpowers       return MP_EQ;
1693*5697Smcpowers 
1694*5697Smcpowers     if(SIGN(a) == ZPOS)
1695*5697Smcpowers       return mag;
1696*5697Smcpowers     else
1697*5697Smcpowers       return -mag;
1698*5697Smcpowers 
1699*5697Smcpowers   } else if(SIGN(a) == ZPOS) {
1700*5697Smcpowers     return MP_GT;
1701*5697Smcpowers   } else {
1702*5697Smcpowers     return MP_LT;
1703*5697Smcpowers   }
1704*5697Smcpowers 
1705*5697Smcpowers } /* end mp_cmp() */
1706*5697Smcpowers 
1707*5697Smcpowers /* }}} */
1708*5697Smcpowers 
1709*5697Smcpowers /* {{{ mp_cmp_mag(a, b) */
1710*5697Smcpowers 
1711*5697Smcpowers /*
1712*5697Smcpowers   mp_cmp_mag(a, b)
1713*5697Smcpowers 
1714*5697Smcpowers   Compares |a| <=> |b|, and returns an appropriate comparison result
1715*5697Smcpowers  */
1716*5697Smcpowers 
1717*5697Smcpowers int    mp_cmp_mag(mp_int *a, mp_int *b)
1718*5697Smcpowers {
1719*5697Smcpowers   ARGCHK(a != NULL && b != NULL, MP_EQ);
1720*5697Smcpowers 
1721*5697Smcpowers   return s_mp_cmp(a, b);
1722*5697Smcpowers 
1723*5697Smcpowers } /* end mp_cmp_mag() */
1724*5697Smcpowers 
1725*5697Smcpowers /* }}} */
1726*5697Smcpowers 
1727*5697Smcpowers /* {{{ mp_cmp_int(a, z, kmflag) */
1728*5697Smcpowers 
1729*5697Smcpowers /*
1730*5697Smcpowers   This just converts z to an mp_int, and uses the existing comparison
1731*5697Smcpowers   routines.  This is sort of inefficient, but it's not clear to me how
1732*5697Smcpowers   frequently this wil get used anyway.  For small positive constants,
1733*5697Smcpowers   you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().
1734*5697Smcpowers  */
1735*5697Smcpowers int    mp_cmp_int(const mp_int *a, long z, int kmflag)
1736*5697Smcpowers {
1737*5697Smcpowers   mp_int  tmp;
1738*5697Smcpowers   int     out;
1739*5697Smcpowers 
1740*5697Smcpowers   ARGCHK(a != NULL, MP_EQ);
1741*5697Smcpowers 
1742*5697Smcpowers   mp_init(&tmp, kmflag); mp_set_int(&tmp, z);
1743*5697Smcpowers   out = mp_cmp(a, &tmp);
1744*5697Smcpowers   mp_clear(&tmp);
1745*5697Smcpowers 
1746*5697Smcpowers   return out;
1747*5697Smcpowers 
1748*5697Smcpowers } /* end mp_cmp_int() */
1749*5697Smcpowers 
1750*5697Smcpowers /* }}} */
1751*5697Smcpowers 
1752*5697Smcpowers /* {{{ mp_isodd(a) */
1753*5697Smcpowers 
1754*5697Smcpowers /*
1755*5697Smcpowers   mp_isodd(a)
1756*5697Smcpowers 
1757*5697Smcpowers   Returns a true (non-zero) value if a is odd, false (zero) otherwise.
1758*5697Smcpowers  */
1759*5697Smcpowers int    mp_isodd(const mp_int *a)
1760*5697Smcpowers {
1761*5697Smcpowers   ARGCHK(a != NULL, 0);
1762*5697Smcpowers 
1763*5697Smcpowers   return (int)(DIGIT(a, 0) & 1);
1764*5697Smcpowers 
1765*5697Smcpowers } /* end mp_isodd() */
1766*5697Smcpowers 
1767*5697Smcpowers /* }}} */
1768*5697Smcpowers 
1769*5697Smcpowers /* {{{ mp_iseven(a) */
1770*5697Smcpowers 
1771*5697Smcpowers int    mp_iseven(const mp_int *a)
1772*5697Smcpowers {
1773*5697Smcpowers   return !mp_isodd(a);
1774*5697Smcpowers 
1775*5697Smcpowers } /* end mp_iseven() */
1776*5697Smcpowers 
1777*5697Smcpowers /* }}} */
1778*5697Smcpowers 
1779*5697Smcpowers /* }}} */
1780*5697Smcpowers 
1781*5697Smcpowers /*------------------------------------------------------------------------*/
1782*5697Smcpowers /* {{{ Number theoretic functions */
1783*5697Smcpowers 
1784*5697Smcpowers #if MP_NUMTH
1785*5697Smcpowers /* {{{ mp_gcd(a, b, c) */
1786*5697Smcpowers 
1787*5697Smcpowers /*
1788*5697Smcpowers   Like the old mp_gcd() function, except computes the GCD using the
1789*5697Smcpowers   binary algorithm due to Josef Stein in 1961 (via Knuth).
1790*5697Smcpowers  */
1791*5697Smcpowers mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
1792*5697Smcpowers {
1793*5697Smcpowers   mp_err   res;
1794*5697Smcpowers   mp_int   u, v, t;
1795*5697Smcpowers   mp_size  k = 0;
1796*5697Smcpowers 
1797*5697Smcpowers   ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
1798*5697Smcpowers 
1799*5697Smcpowers   if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)
1800*5697Smcpowers       return MP_RANGE;
1801*5697Smcpowers   if(mp_cmp_z(a) == MP_EQ) {
1802*5697Smcpowers     return mp_copy(b, c);
1803*5697Smcpowers   } else if(mp_cmp_z(b) == MP_EQ) {
1804*5697Smcpowers     return mp_copy(a, c);
1805*5697Smcpowers   }
1806*5697Smcpowers 
1807*5697Smcpowers   if((res = mp_init(&t, FLAG(a))) != MP_OKAY)
1808*5697Smcpowers     return res;
1809*5697Smcpowers   if((res = mp_init_copy(&u, a)) != MP_OKAY)
1810*5697Smcpowers     goto U;
1811*5697Smcpowers   if((res = mp_init_copy(&v, b)) != MP_OKAY)
1812*5697Smcpowers     goto V;
1813*5697Smcpowers 
1814*5697Smcpowers   SIGN(&u) = ZPOS;
1815*5697Smcpowers   SIGN(&v) = ZPOS;
1816*5697Smcpowers 
1817*5697Smcpowers   /* Divide out common factors of 2 until at least 1 of a, b is even */
1818*5697Smcpowers   while(mp_iseven(&u) && mp_iseven(&v)) {
1819*5697Smcpowers     s_mp_div_2(&u);
1820*5697Smcpowers     s_mp_div_2(&v);
1821*5697Smcpowers     ++k;
1822*5697Smcpowers   }
1823*5697Smcpowers 
1824*5697Smcpowers   /* Initialize t */
1825*5697Smcpowers   if(mp_isodd(&u)) {
1826*5697Smcpowers     if((res = mp_copy(&v, &t)) != MP_OKAY)
1827*5697Smcpowers       goto CLEANUP;
1828*5697Smcpowers 
1829*5697Smcpowers     /* t = -v */
1830*5697Smcpowers     if(SIGN(&v) == ZPOS)
1831*5697Smcpowers       SIGN(&t) = NEG;
1832*5697Smcpowers     else
1833*5697Smcpowers       SIGN(&t) = ZPOS;
1834*5697Smcpowers 
1835*5697Smcpowers   } else {
1836*5697Smcpowers     if((res = mp_copy(&u, &t)) != MP_OKAY)
1837*5697Smcpowers       goto CLEANUP;
1838*5697Smcpowers 
1839*5697Smcpowers   }
1840*5697Smcpowers 
1841*5697Smcpowers   for(;;) {
1842*5697Smcpowers     while(mp_iseven(&t)) {
1843*5697Smcpowers       s_mp_div_2(&t);
1844*5697Smcpowers     }
1845*5697Smcpowers 
1846*5697Smcpowers     if(mp_cmp_z(&t) == MP_GT) {
1847*5697Smcpowers       if((res = mp_copy(&t, &u)) != MP_OKAY)
1848*5697Smcpowers 	goto CLEANUP;
1849*5697Smcpowers 
1850*5697Smcpowers     } else {
1851*5697Smcpowers       if((res = mp_copy(&t, &v)) != MP_OKAY)
1852*5697Smcpowers 	goto CLEANUP;
1853*5697Smcpowers 
1854*5697Smcpowers       /* v = -t */
1855*5697Smcpowers       if(SIGN(&t) == ZPOS)
1856*5697Smcpowers 	SIGN(&v) = NEG;
1857*5697Smcpowers       else
1858*5697Smcpowers 	SIGN(&v) = ZPOS;
1859*5697Smcpowers     }
1860*5697Smcpowers 
1861*5697Smcpowers     if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
1862*5697Smcpowers       goto CLEANUP;
1863*5697Smcpowers 
1864*5697Smcpowers     if(s_mp_cmp_d(&t, 0) == MP_EQ)
1865*5697Smcpowers       break;
1866*5697Smcpowers   }
1867*5697Smcpowers 
1868*5697Smcpowers   s_mp_2expt(&v, k);       /* v = 2^k   */
1869*5697Smcpowers   res = mp_mul(&u, &v, c); /* c = u * v */
1870*5697Smcpowers 
1871*5697Smcpowers  CLEANUP:
1872*5697Smcpowers   mp_clear(&v);
1873*5697Smcpowers  V:
1874*5697Smcpowers   mp_clear(&u);
1875*5697Smcpowers  U:
1876*5697Smcpowers   mp_clear(&t);
1877*5697Smcpowers 
1878*5697Smcpowers   return res;
1879*5697Smcpowers 
1880*5697Smcpowers } /* end mp_gcd() */
1881*5697Smcpowers 
1882*5697Smcpowers /* }}} */
1883*5697Smcpowers 
1884*5697Smcpowers /* {{{ mp_lcm(a, b, c) */
1885*5697Smcpowers 
1886*5697Smcpowers /* We compute the least common multiple using the rule:
1887*5697Smcpowers 
1888*5697Smcpowers    ab = [a, b](a, b)
1889*5697Smcpowers 
1890*5697Smcpowers    ... by computing the product, and dividing out the gcd.
1891*5697Smcpowers  */
1892*5697Smcpowers 
1893*5697Smcpowers mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
1894*5697Smcpowers {
1895*5697Smcpowers   mp_int  gcd, prod;
1896*5697Smcpowers   mp_err  res;
1897*5697Smcpowers 
1898*5697Smcpowers   ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
1899*5697Smcpowers 
1900*5697Smcpowers   /* Set up temporaries */
1901*5697Smcpowers   if((res = mp_init(&gcd, FLAG(a))) != MP_OKAY)
1902*5697Smcpowers     return res;
1903*5697Smcpowers   if((res = mp_init(&prod, FLAG(a))) != MP_OKAY)
1904*5697Smcpowers     goto GCD;
1905*5697Smcpowers 
1906*5697Smcpowers   if((res = mp_mul(a, b, &prod)) != MP_OKAY)
1907*5697Smcpowers     goto CLEANUP;
1908*5697Smcpowers   if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)
1909*5697Smcpowers     goto CLEANUP;
1910*5697Smcpowers 
1911*5697Smcpowers   res = mp_div(&prod, &gcd, c, NULL);
1912*5697Smcpowers 
1913*5697Smcpowers  CLEANUP:
1914*5697Smcpowers   mp_clear(&prod);
1915*5697Smcpowers  GCD:
1916*5697Smcpowers   mp_clear(&gcd);
1917*5697Smcpowers 
1918*5697Smcpowers   return res;
1919*5697Smcpowers 
1920*5697Smcpowers } /* end mp_lcm() */
1921*5697Smcpowers 
1922*5697Smcpowers /* }}} */
1923*5697Smcpowers 
1924*5697Smcpowers /* {{{ mp_xgcd(a, b, g, x, y) */
1925*5697Smcpowers 
1926*5697Smcpowers /*
1927*5697Smcpowers   mp_xgcd(a, b, g, x, y)
1928*5697Smcpowers 
1929*5697Smcpowers   Compute g = (a, b) and values x and y satisfying Bezout's identity
1930*5697Smcpowers   (that is, ax + by = g).  This uses the binary extended GCD algorithm
1931*5697Smcpowers   based on the Stein algorithm used for mp_gcd()
1932*5697Smcpowers   See algorithm 14.61 in Handbook of Applied Cryptogrpahy.
1933*5697Smcpowers  */
1934*5697Smcpowers 
1935*5697Smcpowers mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y)
1936*5697Smcpowers {
1937*5697Smcpowers   mp_int   gx, xc, yc, u, v, A, B, C, D;
1938*5697Smcpowers   mp_int  *clean[9];
1939*5697Smcpowers   mp_err   res;
1940*5697Smcpowers   int      last = -1;
1941*5697Smcpowers 
1942*5697Smcpowers   if(mp_cmp_z(b) == 0)
1943*5697Smcpowers     return MP_RANGE;
1944*5697Smcpowers 
1945*5697Smcpowers   /* Initialize all these variables we need */
1946*5697Smcpowers   MP_CHECKOK( mp_init(&u, FLAG(a)) );
1947*5697Smcpowers   clean[++last] = &u;
1948*5697Smcpowers   MP_CHECKOK( mp_init(&v, FLAG(a)) );
1949*5697Smcpowers   clean[++last] = &v;
1950*5697Smcpowers   MP_CHECKOK( mp_init(&gx, FLAG(a)) );
1951*5697Smcpowers   clean[++last] = &gx;
1952*5697Smcpowers   MP_CHECKOK( mp_init(&A, FLAG(a)) );
1953*5697Smcpowers   clean[++last] = &A;
1954*5697Smcpowers   MP_CHECKOK( mp_init(&B, FLAG(a)) );
1955*5697Smcpowers   clean[++last] = &B;
1956*5697Smcpowers   MP_CHECKOK( mp_init(&C, FLAG(a)) );
1957*5697Smcpowers   clean[++last] = &C;
1958*5697Smcpowers   MP_CHECKOK( mp_init(&D, FLAG(a)) );
1959*5697Smcpowers   clean[++last] = &D;
1960*5697Smcpowers   MP_CHECKOK( mp_init_copy(&xc, a) );
1961*5697Smcpowers   clean[++last] = &xc;
1962*5697Smcpowers   mp_abs(&xc, &xc);
1963*5697Smcpowers   MP_CHECKOK( mp_init_copy(&yc, b) );
1964*5697Smcpowers   clean[++last] = &yc;
1965*5697Smcpowers   mp_abs(&yc, &yc);
1966*5697Smcpowers 
1967*5697Smcpowers   mp_set(&gx, 1);
1968*5697Smcpowers 
1969*5697Smcpowers   /* Divide by two until at least one of them is odd */
1970*5697Smcpowers   while(mp_iseven(&xc) && mp_iseven(&yc)) {
1971*5697Smcpowers     mp_size nx = mp_trailing_zeros(&xc);
1972*5697Smcpowers     mp_size ny = mp_trailing_zeros(&yc);
1973*5697Smcpowers     mp_size n  = MP_MIN(nx, ny);
1974*5697Smcpowers     s_mp_div_2d(&xc,n);
1975*5697Smcpowers     s_mp_div_2d(&yc,n);
1976*5697Smcpowers     MP_CHECKOK( s_mp_mul_2d(&gx,n) );
1977*5697Smcpowers   }
1978*5697Smcpowers 
1979*5697Smcpowers   mp_copy(&xc, &u);
1980*5697Smcpowers   mp_copy(&yc, &v);
1981*5697Smcpowers   mp_set(&A, 1); mp_set(&D, 1);
1982*5697Smcpowers 
1983*5697Smcpowers   /* Loop through binary GCD algorithm */
1984*5697Smcpowers   do {
1985*5697Smcpowers     while(mp_iseven(&u)) {
1986*5697Smcpowers       s_mp_div_2(&u);
1987*5697Smcpowers 
1988*5697Smcpowers       if(mp_iseven(&A) && mp_iseven(&B)) {
1989*5697Smcpowers 	s_mp_div_2(&A); s_mp_div_2(&B);
1990*5697Smcpowers       } else {
1991*5697Smcpowers 	MP_CHECKOK( mp_add(&A, &yc, &A) );
1992*5697Smcpowers 	s_mp_div_2(&A);
1993*5697Smcpowers 	MP_CHECKOK( mp_sub(&B, &xc, &B) );
1994*5697Smcpowers 	s_mp_div_2(&B);
1995*5697Smcpowers       }
1996*5697Smcpowers     }
1997*5697Smcpowers 
1998*5697Smcpowers     while(mp_iseven(&v)) {
1999*5697Smcpowers       s_mp_div_2(&v);
2000*5697Smcpowers 
2001*5697Smcpowers       if(mp_iseven(&C) && mp_iseven(&D)) {
2002*5697Smcpowers 	s_mp_div_2(&C); s_mp_div_2(&D);
2003*5697Smcpowers       } else {
2004*5697Smcpowers 	MP_CHECKOK( mp_add(&C, &yc, &C) );
2005*5697Smcpowers 	s_mp_div_2(&C);
2006*5697Smcpowers 	MP_CHECKOK( mp_sub(&D, &xc, &D) );
2007*5697Smcpowers 	s_mp_div_2(&D);
2008*5697Smcpowers       }
2009*5697Smcpowers     }
2010*5697Smcpowers 
2011*5697Smcpowers     if(mp_cmp(&u, &v) >= 0) {
2012*5697Smcpowers       MP_CHECKOK( mp_sub(&u, &v, &u) );
2013*5697Smcpowers       MP_CHECKOK( mp_sub(&A, &C, &A) );
2014*5697Smcpowers       MP_CHECKOK( mp_sub(&B, &D, &B) );
2015*5697Smcpowers     } else {
2016*5697Smcpowers       MP_CHECKOK( mp_sub(&v, &u, &v) );
2017*5697Smcpowers       MP_CHECKOK( mp_sub(&C, &A, &C) );
2018*5697Smcpowers       MP_CHECKOK( mp_sub(&D, &B, &D) );
2019*5697Smcpowers     }
2020*5697Smcpowers   } while (mp_cmp_z(&u) != 0);
2021*5697Smcpowers 
2022*5697Smcpowers   /* copy results to output */
2023*5697Smcpowers   if(x)
2024*5697Smcpowers     MP_CHECKOK( mp_copy(&C, x) );
2025*5697Smcpowers 
2026*5697Smcpowers   if(y)
2027*5697Smcpowers     MP_CHECKOK( mp_copy(&D, y) );
2028*5697Smcpowers 
2029*5697Smcpowers   if(g)
2030*5697Smcpowers     MP_CHECKOK( mp_mul(&gx, &v, g) );
2031*5697Smcpowers 
2032*5697Smcpowers  CLEANUP:
2033*5697Smcpowers   while(last >= 0)
2034*5697Smcpowers     mp_clear(clean[last--]);
2035*5697Smcpowers 
2036*5697Smcpowers   return res;
2037*5697Smcpowers 
2038*5697Smcpowers } /* end mp_xgcd() */
2039*5697Smcpowers 
2040*5697Smcpowers /* }}} */
2041*5697Smcpowers 
2042*5697Smcpowers mp_size mp_trailing_zeros(const mp_int *mp)
2043*5697Smcpowers {
2044*5697Smcpowers   mp_digit d;
2045*5697Smcpowers   mp_size  n = 0;
2046*5697Smcpowers   int      ix;
2047*5697Smcpowers 
2048*5697Smcpowers   if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))
2049*5697Smcpowers     return n;
2050*5697Smcpowers 
2051*5697Smcpowers   for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix)
2052*5697Smcpowers     n += MP_DIGIT_BIT;
2053*5697Smcpowers   if (!d)
2054*5697Smcpowers     return 0;	/* shouldn't happen, but ... */
2055*5697Smcpowers #if !defined(MP_USE_UINT_DIGIT)
2056*5697Smcpowers   if (!(d & 0xffffffffU)) {
2057*5697Smcpowers     d >>= 32;
2058*5697Smcpowers     n  += 32;
2059*5697Smcpowers   }
2060*5697Smcpowers #endif
2061*5697Smcpowers   if (!(d & 0xffffU)) {
2062*5697Smcpowers     d >>= 16;
2063*5697Smcpowers     n  += 16;
2064*5697Smcpowers   }
2065*5697Smcpowers   if (!(d & 0xffU)) {
2066*5697Smcpowers     d >>= 8;
2067*5697Smcpowers     n  += 8;
2068*5697Smcpowers   }
2069*5697Smcpowers   if (!(d & 0xfU)) {
2070*5697Smcpowers     d >>= 4;
2071*5697Smcpowers     n  += 4;
2072*5697Smcpowers   }
2073*5697Smcpowers   if (!(d & 0x3U)) {
2074*5697Smcpowers     d >>= 2;
2075*5697Smcpowers     n  += 2;
2076*5697Smcpowers   }
2077*5697Smcpowers   if (!(d & 0x1U)) {
2078*5697Smcpowers     d >>= 1;
2079*5697Smcpowers     n  += 1;
2080*5697Smcpowers   }
2081*5697Smcpowers #if MP_ARGCHK == 2
2082*5697Smcpowers   assert(0 != (d & 1));
2083*5697Smcpowers #endif
2084*5697Smcpowers   return n;
2085*5697Smcpowers }
2086*5697Smcpowers 
2087*5697Smcpowers /* Given a and prime p, computes c and k such that a*c == 2**k (mod p).
2088*5697Smcpowers ** Returns k (positive) or error (negative).
2089*5697Smcpowers ** This technique from the paper "Fast Modular Reciprocals" (unpublished)
2090*5697Smcpowers ** by Richard Schroeppel (a.k.a. Captain Nemo).
2091*5697Smcpowers */
2092*5697Smcpowers mp_err s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)
2093*5697Smcpowers {
2094*5697Smcpowers   mp_err res;
2095*5697Smcpowers   mp_err k    = 0;
2096*5697Smcpowers   mp_int d, f, g;
2097*5697Smcpowers 
2098*5697Smcpowers   ARGCHK(a && p && c, MP_BADARG);
2099*5697Smcpowers 
2100*5697Smcpowers   MP_DIGITS(&d) = 0;
2101*5697Smcpowers   MP_DIGITS(&f) = 0;
2102*5697Smcpowers   MP_DIGITS(&g) = 0;
2103*5697Smcpowers   MP_CHECKOK( mp_init(&d, FLAG(a)) );
2104*5697Smcpowers   MP_CHECKOK( mp_init_copy(&f, a) );	/* f = a */
2105*5697Smcpowers   MP_CHECKOK( mp_init_copy(&g, p) );	/* g = p */
2106*5697Smcpowers 
2107*5697Smcpowers   mp_set(c, 1);
2108*5697Smcpowers   mp_zero(&d);
2109*5697Smcpowers 
2110*5697Smcpowers   if (mp_cmp_z(&f) == 0) {
2111*5697Smcpowers     res = MP_UNDEF;
2112*5697Smcpowers   } else
2113*5697Smcpowers   for (;;) {
2114*5697Smcpowers     int diff_sign;
2115*5697Smcpowers     while (mp_iseven(&f)) {
2116*5697Smcpowers       mp_size n = mp_trailing_zeros(&f);
2117*5697Smcpowers       if (!n) {
2118*5697Smcpowers 	res = MP_UNDEF;
2119*5697Smcpowers 	goto CLEANUP;
2120*5697Smcpowers       }
2121*5697Smcpowers       s_mp_div_2d(&f, n);
2122*5697Smcpowers       MP_CHECKOK( s_mp_mul_2d(&d, n) );
2123*5697Smcpowers       k += n;
2124*5697Smcpowers     }
2125*5697Smcpowers     if (mp_cmp_d(&f, 1) == MP_EQ) {	/* f == 1 */
2126*5697Smcpowers       res = k;
2127*5697Smcpowers       break;
2128*5697Smcpowers     }
2129*5697Smcpowers     diff_sign = mp_cmp(&f, &g);
2130*5697Smcpowers     if (diff_sign < 0) {		/* f < g */
2131*5697Smcpowers       s_mp_exch(&f, &g);
2132*5697Smcpowers       s_mp_exch(c, &d);
2133*5697Smcpowers     } else if (diff_sign == 0) {		/* f == g */
2134*5697Smcpowers       res = MP_UNDEF;		/* a and p are not relatively prime */
2135*5697Smcpowers       break;
2136*5697Smcpowers     }
2137*5697Smcpowers     if ((MP_DIGIT(&f,0) % 4) == (MP_DIGIT(&g,0) % 4)) {
2138*5697Smcpowers       MP_CHECKOK( mp_sub(&f, &g, &f) );	/* f = f - g */
2139*5697Smcpowers       MP_CHECKOK( mp_sub(c,  &d,  c) );	/* c = c - d */
2140*5697Smcpowers     } else {
2141*5697Smcpowers       MP_CHECKOK( mp_add(&f, &g, &f) );	/* f = f + g */
2142*5697Smcpowers       MP_CHECKOK( mp_add(c,  &d,  c) );	/* c = c + d */
2143*5697Smcpowers     }
2144*5697Smcpowers   }
2145*5697Smcpowers   if (res >= 0) {
2146*5697Smcpowers     while (MP_SIGN(c) != MP_ZPOS) {
2147*5697Smcpowers       MP_CHECKOK( mp_add(c, p, c) );
2148*5697Smcpowers     }
2149*5697Smcpowers     res = k;
2150*5697Smcpowers   }
2151*5697Smcpowers 
2152*5697Smcpowers CLEANUP:
2153*5697Smcpowers   mp_clear(&d);
2154*5697Smcpowers   mp_clear(&f);
2155*5697Smcpowers   mp_clear(&g);
2156*5697Smcpowers   return res;
2157*5697Smcpowers }
2158*5697Smcpowers 
2159*5697Smcpowers /* Compute T = (P ** -1) mod MP_RADIX.  Also works for 16-bit mp_digits.
2160*5697Smcpowers ** This technique from the paper "Fast Modular Reciprocals" (unpublished)
2161*5697Smcpowers ** by Richard Schroeppel (a.k.a. Captain Nemo).
2162*5697Smcpowers */
2163*5697Smcpowers mp_digit  s_mp_invmod_radix(mp_digit P)
2164*5697Smcpowers {
2165*5697Smcpowers   mp_digit T = P;
2166*5697Smcpowers   T *= 2 - (P * T);
2167*5697Smcpowers   T *= 2 - (P * T);
2168*5697Smcpowers   T *= 2 - (P * T);
2169*5697Smcpowers   T *= 2 - (P * T);
2170*5697Smcpowers #if !defined(MP_USE_UINT_DIGIT)
2171*5697Smcpowers   T *= 2 - (P * T);
2172*5697Smcpowers   T *= 2 - (P * T);
2173*5697Smcpowers #endif
2174*5697Smcpowers   return T;
2175*5697Smcpowers }
2176*5697Smcpowers 
2177*5697Smcpowers /* Given c, k, and prime p, where a*c == 2**k (mod p),
2178*5697Smcpowers ** Compute x = (a ** -1) mod p.  This is similar to Montgomery reduction.
2179*5697Smcpowers ** This technique from the paper "Fast Modular Reciprocals" (unpublished)
2180*5697Smcpowers ** by Richard Schroeppel (a.k.a. Captain Nemo).
2181*5697Smcpowers */
2182*5697Smcpowers mp_err  s_mp_fixup_reciprocal(const mp_int *c, const mp_int *p, int k, mp_int *x)
2183*5697Smcpowers {
2184*5697Smcpowers   int      k_orig = k;
2185*5697Smcpowers   mp_digit r;
2186*5697Smcpowers   mp_size  ix;
2187*5697Smcpowers   mp_err   res;
2188*5697Smcpowers 
2189*5697Smcpowers   if (mp_cmp_z(c) < 0) {		/* c < 0 */
2190*5697Smcpowers     MP_CHECKOK( mp_add(c, p, x) );	/* x = c + p */
2191*5697Smcpowers   } else {
2192*5697Smcpowers     MP_CHECKOK( mp_copy(c, x) );	/* x = c */
2193*5697Smcpowers   }
2194*5697Smcpowers 
2195*5697Smcpowers   /* make sure x is large enough */
2196*5697Smcpowers   ix = MP_HOWMANY(k, MP_DIGIT_BIT) + MP_USED(p) + 1;
2197*5697Smcpowers   ix = MP_MAX(ix, MP_USED(x));
2198*5697Smcpowers   MP_CHECKOK( s_mp_pad(x, ix) );
2199*5697Smcpowers 
2200*5697Smcpowers   r = 0 - s_mp_invmod_radix(MP_DIGIT(p,0));
2201*5697Smcpowers 
2202*5697Smcpowers   for (ix = 0; k > 0; ix++) {
2203*5697Smcpowers     int      j = MP_MIN(k, MP_DIGIT_BIT);
2204*5697Smcpowers     mp_digit v = r * MP_DIGIT(x, ix);
2205*5697Smcpowers     if (j < MP_DIGIT_BIT) {
2206*5697Smcpowers       v &= ((mp_digit)1 << j) - 1;	/* v = v mod (2 ** j) */
2207*5697Smcpowers     }
2208*5697Smcpowers     s_mp_mul_d_add_offset(p, v, x, ix); /* x += p * v * (RADIX ** ix) */
2209*5697Smcpowers     k -= j;
2210*5697Smcpowers   }
2211*5697Smcpowers   s_mp_clamp(x);
2212*5697Smcpowers   s_mp_div_2d(x, k_orig);
2213*5697Smcpowers   res = MP_OKAY;
2214*5697Smcpowers 
2215*5697Smcpowers CLEANUP:
2216*5697Smcpowers   return res;
2217*5697Smcpowers }
2218*5697Smcpowers 
2219*5697Smcpowers /* compute mod inverse using Schroeppel's method, only if m is odd */
2220*5697Smcpowers mp_err s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c)
2221*5697Smcpowers {
2222*5697Smcpowers   int k;
2223*5697Smcpowers   mp_err  res;
2224*5697Smcpowers   mp_int  x;
2225*5697Smcpowers 
2226*5697Smcpowers   ARGCHK(a && m && c, MP_BADARG);
2227*5697Smcpowers 
2228*5697Smcpowers   if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
2229*5697Smcpowers     return MP_RANGE;
2230*5697Smcpowers   if (mp_iseven(m))
2231*5697Smcpowers     return MP_UNDEF;
2232*5697Smcpowers 
2233*5697Smcpowers   MP_DIGITS(&x) = 0;
2234*5697Smcpowers 
2235*5697Smcpowers   if (a == c) {
2236*5697Smcpowers     if ((res = mp_init_copy(&x, a)) != MP_OKAY)
2237*5697Smcpowers       return res;
2238*5697Smcpowers     if (a == m)
2239*5697Smcpowers       m = &x;
2240*5697Smcpowers     a = &x;
2241*5697Smcpowers   } else if (m == c) {
2242*5697Smcpowers     if ((res = mp_init_copy(&x, m)) != MP_OKAY)
2243*5697Smcpowers       return res;
2244*5697Smcpowers     m = &x;
2245*5697Smcpowers   } else {
2246*5697Smcpowers     MP_DIGITS(&x) = 0;
2247*5697Smcpowers   }
2248*5697Smcpowers 
2249*5697Smcpowers   MP_CHECKOK( s_mp_almost_inverse(a, m, c) );
2250*5697Smcpowers   k = res;
2251*5697Smcpowers   MP_CHECKOK( s_mp_fixup_reciprocal(c, m, k, c) );
2252*5697Smcpowers CLEANUP:
2253*5697Smcpowers   mp_clear(&x);
2254*5697Smcpowers   return res;
2255*5697Smcpowers }
2256*5697Smcpowers 
2257*5697Smcpowers /* Known good algorithm for computing modular inverse.  But slow. */
2258*5697Smcpowers mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c)
2259*5697Smcpowers {
2260*5697Smcpowers   mp_int  g, x;
2261*5697Smcpowers   mp_err  res;
2262*5697Smcpowers 
2263*5697Smcpowers   ARGCHK(a && m && c, MP_BADARG);
2264*5697Smcpowers 
2265*5697Smcpowers   if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
2266*5697Smcpowers     return MP_RANGE;
2267*5697Smcpowers 
2268*5697Smcpowers   MP_DIGITS(&g) = 0;
2269*5697Smcpowers   MP_DIGITS(&x) = 0;
2270*5697Smcpowers   MP_CHECKOK( mp_init(&x, FLAG(a)) );
2271*5697Smcpowers   MP_CHECKOK( mp_init(&g, FLAG(a)) );
2272*5697Smcpowers 
2273*5697Smcpowers   MP_CHECKOK( mp_xgcd(a, m, &g, &x, NULL) );
2274*5697Smcpowers 
2275*5697Smcpowers   if (mp_cmp_d(&g, 1) != MP_EQ) {
2276*5697Smcpowers     res = MP_UNDEF;
2277*5697Smcpowers     goto CLEANUP;
2278*5697Smcpowers   }
2279*5697Smcpowers 
2280*5697Smcpowers   res = mp_mod(&x, m, c);
2281*5697Smcpowers   SIGN(c) = SIGN(a);
2282*5697Smcpowers 
2283*5697Smcpowers CLEANUP:
2284*5697Smcpowers   mp_clear(&x);
2285*5697Smcpowers   mp_clear(&g);
2286*5697Smcpowers 
2287*5697Smcpowers   return res;
2288*5697Smcpowers }
2289*5697Smcpowers 
2290*5697Smcpowers /* modular inverse where modulus is 2**k. */
2291*5697Smcpowers /* c = a**-1 mod 2**k */
2292*5697Smcpowers mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c)
2293*5697Smcpowers {
2294*5697Smcpowers   mp_err res;
2295*5697Smcpowers   mp_size ix = k + 4;
2296*5697Smcpowers   mp_int t0, t1, val, tmp, two2k;
2297*5697Smcpowers 
2298*5697Smcpowers   static const mp_digit d2 = 2;
2299*5697Smcpowers   static const mp_int two = { 0, MP_ZPOS, 1, 1, (mp_digit *)&d2 };
2300*5697Smcpowers 
2301*5697Smcpowers   if (mp_iseven(a))
2302*5697Smcpowers     return MP_UNDEF;
2303*5697Smcpowers   if (k <= MP_DIGIT_BIT) {
2304*5697Smcpowers     mp_digit i = s_mp_invmod_radix(MP_DIGIT(a,0));
2305*5697Smcpowers     if (k < MP_DIGIT_BIT)
2306*5697Smcpowers       i &= ((mp_digit)1 << k) - (mp_digit)1;
2307*5697Smcpowers     mp_set(c, i);
2308*5697Smcpowers     return MP_OKAY;
2309*5697Smcpowers   }
2310*5697Smcpowers   MP_DIGITS(&t0) = 0;
2311*5697Smcpowers   MP_DIGITS(&t1) = 0;
2312*5697Smcpowers   MP_DIGITS(&val) = 0;
2313*5697Smcpowers   MP_DIGITS(&tmp) = 0;
2314*5697Smcpowers   MP_DIGITS(&two2k) = 0;
2315*5697Smcpowers   MP_CHECKOK( mp_init_copy(&val, a) );
2316*5697Smcpowers   s_mp_mod_2d(&val, k);
2317*5697Smcpowers   MP_CHECKOK( mp_init_copy(&t0, &val) );
2318*5697Smcpowers   MP_CHECKOK( mp_init_copy(&t1, &t0)  );
2319*5697Smcpowers   MP_CHECKOK( mp_init(&tmp, FLAG(a)) );
2320*5697Smcpowers   MP_CHECKOK( mp_init(&two2k, FLAG(a)) );
2321*5697Smcpowers   MP_CHECKOK( s_mp_2expt(&two2k, k) );
2322*5697Smcpowers   do {
2323*5697Smcpowers     MP_CHECKOK( mp_mul(&val, &t1, &tmp)  );
2324*5697Smcpowers     MP_CHECKOK( mp_sub(&two, &tmp, &tmp) );
2325*5697Smcpowers     MP_CHECKOK( mp_mul(&t1, &tmp, &t1)   );
2326*5697Smcpowers     s_mp_mod_2d(&t1, k);
2327*5697Smcpowers     while (MP_SIGN(&t1) != MP_ZPOS) {
2328*5697Smcpowers       MP_CHECKOK( mp_add(&t1, &two2k, &t1) );
2329*5697Smcpowers     }
2330*5697Smcpowers     if (mp_cmp(&t1, &t0) == MP_EQ)
2331*5697Smcpowers       break;
2332*5697Smcpowers     MP_CHECKOK( mp_copy(&t1, &t0) );
2333*5697Smcpowers   } while (--ix > 0);
2334*5697Smcpowers   if (!ix) {
2335*5697Smcpowers     res = MP_UNDEF;
2336*5697Smcpowers   } else {
2337*5697Smcpowers     mp_exch(c, &t1);
2338*5697Smcpowers   }
2339*5697Smcpowers 
2340*5697Smcpowers CLEANUP:
2341*5697Smcpowers   mp_clear(&t0);
2342*5697Smcpowers   mp_clear(&t1);
2343*5697Smcpowers   mp_clear(&val);
2344*5697Smcpowers   mp_clear(&tmp);
2345*5697Smcpowers   mp_clear(&two2k);
2346*5697Smcpowers   return res;
2347*5697Smcpowers }
2348*5697Smcpowers 
2349*5697Smcpowers mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c)
2350*5697Smcpowers {
2351*5697Smcpowers   mp_err res;
2352*5697Smcpowers   mp_size k;
2353*5697Smcpowers   mp_int oddFactor, evenFactor;	/* factors of the modulus */
2354*5697Smcpowers   mp_int oddPart, evenPart;	/* parts to combine via CRT. */
2355*5697Smcpowers   mp_int C2, tmp1, tmp2;
2356*5697Smcpowers 
2357*5697Smcpowers   /*static const mp_digit d1 = 1; */
2358*5697Smcpowers   /*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */
2359*5697Smcpowers 
2360*5697Smcpowers   if ((res = s_mp_ispow2(m)) >= 0) {
2361*5697Smcpowers     k = res;
2362*5697Smcpowers     return s_mp_invmod_2d(a, k, c);
2363*5697Smcpowers   }
2364*5697Smcpowers   MP_DIGITS(&oddFactor) = 0;
2365*5697Smcpowers   MP_DIGITS(&evenFactor) = 0;
2366*5697Smcpowers   MP_DIGITS(&oddPart) = 0;
2367*5697Smcpowers   MP_DIGITS(&evenPart) = 0;
2368*5697Smcpowers   MP_DIGITS(&C2)     = 0;
2369*5697Smcpowers   MP_DIGITS(&tmp1)   = 0;
2370*5697Smcpowers   MP_DIGITS(&tmp2)   = 0;
2371*5697Smcpowers 
2372*5697Smcpowers   MP_CHECKOK( mp_init_copy(&oddFactor, m) );    /* oddFactor = m */
2373*5697Smcpowers   MP_CHECKOK( mp_init(&evenFactor, FLAG(m)) );
2374*5697Smcpowers   MP_CHECKOK( mp_init(&oddPart, FLAG(m)) );
2375*5697Smcpowers   MP_CHECKOK( mp_init(&evenPart, FLAG(m)) );
2376*5697Smcpowers   MP_CHECKOK( mp_init(&C2, FLAG(m))     );
2377*5697Smcpowers   MP_CHECKOK( mp_init(&tmp1, FLAG(m))   );
2378*5697Smcpowers   MP_CHECKOK( mp_init(&tmp2, FLAG(m))   );
2379*5697Smcpowers 
2380*5697Smcpowers   k = mp_trailing_zeros(m);
2381*5697Smcpowers   s_mp_div_2d(&oddFactor, k);
2382*5697Smcpowers   MP_CHECKOK( s_mp_2expt(&evenFactor, k) );
2383*5697Smcpowers 
2384*5697Smcpowers   /* compute a**-1 mod oddFactor. */
2385*5697Smcpowers   MP_CHECKOK( s_mp_invmod_odd_m(a, &oddFactor, &oddPart) );
2386*5697Smcpowers   /* compute a**-1 mod evenFactor, where evenFactor == 2**k. */
2387*5697Smcpowers   MP_CHECKOK( s_mp_invmod_2d(   a,       k,    &evenPart) );
2388*5697Smcpowers 
2389*5697Smcpowers   /* Use Chinese Remainer theorem to compute a**-1 mod m. */
2390*5697Smcpowers   /* let m1 = oddFactor,  v1 = oddPart,
2391*5697Smcpowers    * let m2 = evenFactor, v2 = evenPart.
2392*5697Smcpowers    */
2393*5697Smcpowers 
2394*5697Smcpowers   /* Compute C2 = m1**-1 mod m2. */
2395*5697Smcpowers   MP_CHECKOK( s_mp_invmod_2d(&oddFactor, k,    &C2) );
2396*5697Smcpowers 
2397*5697Smcpowers   /* compute u = (v2 - v1)*C2 mod m2 */
2398*5697Smcpowers   MP_CHECKOK( mp_sub(&evenPart, &oddPart,   &tmp1) );
2399*5697Smcpowers   MP_CHECKOK( mp_mul(&tmp1,     &C2,        &tmp2) );
2400*5697Smcpowers   s_mp_mod_2d(&tmp2, k);
2401*5697Smcpowers   while (MP_SIGN(&tmp2) != MP_ZPOS) {
2402*5697Smcpowers     MP_CHECKOK( mp_add(&tmp2, &evenFactor, &tmp2) );
2403*5697Smcpowers   }
2404*5697Smcpowers 
2405*5697Smcpowers   /* compute answer = v1 + u*m1 */
2406*5697Smcpowers   MP_CHECKOK( mp_mul(&tmp2,     &oddFactor, c) );
2407*5697Smcpowers   MP_CHECKOK( mp_add(&oddPart,  c,          c) );
2408*5697Smcpowers   /* not sure this is necessary, but it's low cost if not. */
2409*5697Smcpowers   MP_CHECKOK( mp_mod(c,         m,          c) );
2410*5697Smcpowers 
2411*5697Smcpowers CLEANUP:
2412*5697Smcpowers   mp_clear(&oddFactor);
2413*5697Smcpowers   mp_clear(&evenFactor);
2414*5697Smcpowers   mp_clear(&oddPart);
2415*5697Smcpowers   mp_clear(&evenPart);
2416*5697Smcpowers   mp_clear(&C2);
2417*5697Smcpowers   mp_clear(&tmp1);
2418*5697Smcpowers   mp_clear(&tmp2);
2419*5697Smcpowers   return res;
2420*5697Smcpowers }
2421*5697Smcpowers 
2422*5697Smcpowers 
2423*5697Smcpowers /* {{{ mp_invmod(a, m, c) */
2424*5697Smcpowers 
2425*5697Smcpowers /*
2426*5697Smcpowers   mp_invmod(a, m, c)
2427*5697Smcpowers 
2428*5697Smcpowers   Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
2429*5697Smcpowers   This is equivalent to the question of whether (a, m) = 1.  If not,
2430*5697Smcpowers   MP_UNDEF is returned, and there is no inverse.
2431*5697Smcpowers  */
2432*5697Smcpowers 
2433*5697Smcpowers mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)
2434*5697Smcpowers {
2435*5697Smcpowers 
2436*5697Smcpowers   ARGCHK(a && m && c, MP_BADARG);
2437*5697Smcpowers 
2438*5697Smcpowers   if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
2439*5697Smcpowers     return MP_RANGE;
2440*5697Smcpowers 
2441*5697Smcpowers   if (mp_isodd(m)) {
2442*5697Smcpowers     return s_mp_invmod_odd_m(a, m, c);
2443*5697Smcpowers   }
2444*5697Smcpowers   if (mp_iseven(a))
2445*5697Smcpowers     return MP_UNDEF;	/* not invertable */
2446*5697Smcpowers 
2447*5697Smcpowers   return s_mp_invmod_even_m(a, m, c);
2448*5697Smcpowers 
2449*5697Smcpowers } /* end mp_invmod() */
2450*5697Smcpowers 
2451*5697Smcpowers /* }}} */
2452*5697Smcpowers #endif /* if MP_NUMTH */
2453*5697Smcpowers 
2454*5697Smcpowers /* }}} */
2455*5697Smcpowers 
2456*5697Smcpowers /*------------------------------------------------------------------------*/
2457*5697Smcpowers /* {{{ mp_print(mp, ofp) */
2458*5697Smcpowers 
2459*5697Smcpowers #if MP_IOFUNC
2460*5697Smcpowers /*
2461*5697Smcpowers   mp_print(mp, ofp)
2462*5697Smcpowers 
2463*5697Smcpowers   Print a textual representation of the given mp_int on the output
2464*5697Smcpowers   stream 'ofp'.  Output is generated using the internal radix.
2465*5697Smcpowers  */
2466*5697Smcpowers 
2467*5697Smcpowers void   mp_print(mp_int *mp, FILE *ofp)
2468*5697Smcpowers {
2469*5697Smcpowers   int   ix;
2470*5697Smcpowers 
2471*5697Smcpowers   if(mp == NULL || ofp == NULL)
2472*5697Smcpowers     return;
2473*5697Smcpowers 
2474*5697Smcpowers   fputc((SIGN(mp) == NEG) ? '-' : '+', ofp);
2475*5697Smcpowers 
2476*5697Smcpowers   for(ix = USED(mp) - 1; ix >= 0; ix--) {
2477*5697Smcpowers     fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
2478*5697Smcpowers   }
2479*5697Smcpowers 
2480*5697Smcpowers } /* end mp_print() */
2481*5697Smcpowers 
2482*5697Smcpowers #endif /* if MP_IOFUNC */
2483*5697Smcpowers 
2484*5697Smcpowers /* }}} */
2485*5697Smcpowers 
2486*5697Smcpowers /*------------------------------------------------------------------------*/
2487*5697Smcpowers /* {{{ More I/O Functions */
2488*5697Smcpowers 
2489*5697Smcpowers /* {{{ mp_read_raw(mp, str, len) */
2490*5697Smcpowers 
2491*5697Smcpowers /*
2492*5697Smcpowers    mp_read_raw(mp, str, len)
2493*5697Smcpowers 
2494*5697Smcpowers    Read in a raw value (base 256) into the given mp_int
2495*5697Smcpowers  */
2496*5697Smcpowers 
2497*5697Smcpowers mp_err  mp_read_raw(mp_int *mp, char *str, int len)
2498*5697Smcpowers {
2499*5697Smcpowers   int            ix;
2500*5697Smcpowers   mp_err         res;
2501*5697Smcpowers   unsigned char *ustr = (unsigned char *)str;
2502*5697Smcpowers 
2503*5697Smcpowers   ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
2504*5697Smcpowers 
2505*5697Smcpowers   mp_zero(mp);
2506*5697Smcpowers 
2507*5697Smcpowers   /* Get sign from first byte */
2508*5697Smcpowers   if(ustr[0])
2509*5697Smcpowers     SIGN(mp) = NEG;
2510*5697Smcpowers   else
2511*5697Smcpowers     SIGN(mp) = ZPOS;
2512*5697Smcpowers 
2513*5697Smcpowers   /* Read the rest of the digits */
2514*5697Smcpowers   for(ix = 1; ix < len; ix++) {
2515*5697Smcpowers     if((res = mp_mul_d(mp, 256, mp)) != MP_OKAY)
2516*5697Smcpowers       return res;
2517*5697Smcpowers     if((res = mp_add_d(mp, ustr[ix], mp)) != MP_OKAY)
2518*5697Smcpowers       return res;
2519*5697Smcpowers   }
2520*5697Smcpowers 
2521*5697Smcpowers   return MP_OKAY;
2522*5697Smcpowers 
2523*5697Smcpowers } /* end mp_read_raw() */
2524*5697Smcpowers 
2525*5697Smcpowers /* }}} */
2526*5697Smcpowers 
2527*5697Smcpowers /* {{{ mp_raw_size(mp) */
2528*5697Smcpowers 
2529*5697Smcpowers int    mp_raw_size(mp_int *mp)
2530*5697Smcpowers {
2531*5697Smcpowers   ARGCHK(mp != NULL, 0);
2532*5697Smcpowers 
2533*5697Smcpowers   return (USED(mp) * sizeof(mp_digit)) + 1;
2534*5697Smcpowers 
2535*5697Smcpowers } /* end mp_raw_size() */
2536*5697Smcpowers 
2537*5697Smcpowers /* }}} */
2538*5697Smcpowers 
2539*5697Smcpowers /* {{{ mp_toraw(mp, str) */
2540*5697Smcpowers 
2541*5697Smcpowers mp_err mp_toraw(mp_int *mp, char *str)
2542*5697Smcpowers {
2543*5697Smcpowers   int  ix, jx, pos = 1;
2544*5697Smcpowers 
2545*5697Smcpowers   ARGCHK(mp != NULL && str != NULL, MP_BADARG);
2546*5697Smcpowers 
2547*5697Smcpowers   str[0] = (char)SIGN(mp);
2548*5697Smcpowers 
2549*5697Smcpowers   /* Iterate over each digit... */
2550*5697Smcpowers   for(ix = USED(mp) - 1; ix >= 0; ix--) {
2551*5697Smcpowers     mp_digit  d = DIGIT(mp, ix);
2552*5697Smcpowers 
2553*5697Smcpowers     /* Unpack digit bytes, high order first */
2554*5697Smcpowers     for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
2555*5697Smcpowers       str[pos++] = (char)(d >> (jx * CHAR_BIT));
2556*5697Smcpowers     }
2557*5697Smcpowers   }
2558*5697Smcpowers 
2559*5697Smcpowers   return MP_OKAY;
2560*5697Smcpowers 
2561*5697Smcpowers } /* end mp_toraw() */
2562*5697Smcpowers 
2563*5697Smcpowers /* }}} */
2564*5697Smcpowers 
2565*5697Smcpowers /* {{{ mp_read_radix(mp, str, radix) */
2566*5697Smcpowers 
2567*5697Smcpowers /*
2568*5697Smcpowers   mp_read_radix(mp, str, radix)
2569*5697Smcpowers 
2570*5697Smcpowers   Read an integer from the given string, and set mp to the resulting
2571*5697Smcpowers   value.  The input is presumed to be in base 10.  Leading non-digit
2572*5697Smcpowers   characters are ignored, and the function reads until a non-digit
2573*5697Smcpowers   character or the end of the string.
2574*5697Smcpowers  */
2575*5697Smcpowers 
2576*5697Smcpowers mp_err  mp_read_radix(mp_int *mp, const char *str, int radix)
2577*5697Smcpowers {
2578*5697Smcpowers   int     ix = 0, val = 0;
2579*5697Smcpowers   mp_err  res;
2580*5697Smcpowers   mp_sign sig = ZPOS;
2581*5697Smcpowers 
2582*5697Smcpowers   ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX,
2583*5697Smcpowers 	 MP_BADARG);
2584*5697Smcpowers 
2585*5697Smcpowers   mp_zero(mp);
2586*5697Smcpowers 
2587*5697Smcpowers   /* Skip leading non-digit characters until a digit or '-' or '+' */
2588*5697Smcpowers   while(str[ix] &&
2589*5697Smcpowers 	(s_mp_tovalue(str[ix], radix) < 0) &&
2590*5697Smcpowers 	str[ix] != '-' &&
2591*5697Smcpowers 	str[ix] != '+') {
2592*5697Smcpowers     ++ix;
2593*5697Smcpowers   }
2594*5697Smcpowers 
2595*5697Smcpowers   if(str[ix] == '-') {
2596*5697Smcpowers     sig = NEG;
2597*5697Smcpowers     ++ix;
2598*5697Smcpowers   } else if(str[ix] == '+') {
2599*5697Smcpowers     sig = ZPOS; /* this is the default anyway... */
2600*5697Smcpowers     ++ix;
2601*5697Smcpowers   }
2602*5697Smcpowers 
2603*5697Smcpowers   while((val = s_mp_tovalue(str[ix], radix)) >= 0) {
2604*5697Smcpowers     if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)
2605*5697Smcpowers       return res;
2606*5697Smcpowers     if((res = s_mp_add_d(mp, val)) != MP_OKAY)
2607*5697Smcpowers       return res;
2608*5697Smcpowers     ++ix;
2609*5697Smcpowers   }
2610*5697Smcpowers 
2611*5697Smcpowers   if(s_mp_cmp_d(mp, 0) == MP_EQ)
2612*5697Smcpowers     SIGN(mp) = ZPOS;
2613*5697Smcpowers   else
2614*5697Smcpowers     SIGN(mp) = sig;
2615*5697Smcpowers 
2616*5697Smcpowers   return MP_OKAY;
2617*5697Smcpowers 
2618*5697Smcpowers } /* end mp_read_radix() */
2619*5697Smcpowers 
2620*5697Smcpowers mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix)
2621*5697Smcpowers {
2622*5697Smcpowers   int     radix = default_radix;
2623*5697Smcpowers   int     cx;
2624*5697Smcpowers   mp_sign sig   = ZPOS;
2625*5697Smcpowers   mp_err  res;
2626*5697Smcpowers 
2627*5697Smcpowers   /* Skip leading non-digit characters until a digit or '-' or '+' */
2628*5697Smcpowers   while ((cx = *str) != 0 &&
2629*5697Smcpowers 	(s_mp_tovalue(cx, radix) < 0) &&
2630*5697Smcpowers 	cx != '-' &&
2631*5697Smcpowers 	cx != '+') {
2632*5697Smcpowers     ++str;
2633*5697Smcpowers   }
2634*5697Smcpowers 
2635*5697Smcpowers   if (cx == '-') {
2636*5697Smcpowers     sig = NEG;
2637*5697Smcpowers     ++str;
2638*5697Smcpowers   } else if (cx == '+') {
2639*5697Smcpowers     sig = ZPOS; /* this is the default anyway... */
2640*5697Smcpowers     ++str;
2641*5697Smcpowers   }
2642*5697Smcpowers 
2643*5697Smcpowers   if (str[0] == '0') {
2644*5697Smcpowers     if ((str[1] | 0x20) == 'x') {
2645*5697Smcpowers       radix = 16;
2646*5697Smcpowers       str += 2;
2647*5697Smcpowers     } else {
2648*5697Smcpowers       radix = 8;
2649*5697Smcpowers       str++;
2650*5697Smcpowers     }
2651*5697Smcpowers   }
2652*5697Smcpowers   res = mp_read_radix(a, str, radix);
2653*5697Smcpowers   if (res == MP_OKAY) {
2654*5697Smcpowers     MP_SIGN(a) = (s_mp_cmp_d(a, 0) == MP_EQ) ? ZPOS : sig;
2655*5697Smcpowers   }
2656*5697Smcpowers   return res;
2657*5697Smcpowers }
2658*5697Smcpowers 
2659*5697Smcpowers /* }}} */
2660*5697Smcpowers 
2661*5697Smcpowers /* {{{ mp_radix_size(mp, radix) */
2662*5697Smcpowers 
2663*5697Smcpowers int    mp_radix_size(mp_int *mp, int radix)
2664*5697Smcpowers {
2665*5697Smcpowers   int  bits;
2666*5697Smcpowers 
2667*5697Smcpowers   if(!mp || radix < 2 || radix > MAX_RADIX)
2668*5697Smcpowers     return 0;
2669*5697Smcpowers 
2670*5697Smcpowers   bits = USED(mp) * DIGIT_BIT - 1;
2671*5697Smcpowers 
2672*5697Smcpowers   return s_mp_outlen(bits, radix);
2673*5697Smcpowers 
2674*5697Smcpowers } /* end mp_radix_size() */
2675*5697Smcpowers 
2676*5697Smcpowers /* }}} */
2677*5697Smcpowers 
2678*5697Smcpowers /* {{{ mp_toradix(mp, str, radix) */
2679*5697Smcpowers 
2680*5697Smcpowers mp_err mp_toradix(mp_int *mp, char *str, int radix)
2681*5697Smcpowers {
2682*5697Smcpowers   int  ix, pos = 0;
2683*5697Smcpowers 
2684*5697Smcpowers   ARGCHK(mp != NULL && str != NULL, MP_BADARG);
2685*5697Smcpowers   ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
2686*5697Smcpowers 
2687*5697Smcpowers   if(mp_cmp_z(mp) == MP_EQ) {
2688*5697Smcpowers     str[0] = '0';
2689*5697Smcpowers     str[1] = '\0';
2690*5697Smcpowers   } else {
2691*5697Smcpowers     mp_err   res;
2692*5697Smcpowers     mp_int   tmp;
2693*5697Smcpowers     mp_sign  sgn;
2694*5697Smcpowers     mp_digit rem, rdx = (mp_digit)radix;
2695*5697Smcpowers     char     ch;
2696*5697Smcpowers 
2697*5697Smcpowers     if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
2698*5697Smcpowers       return res;
2699*5697Smcpowers 
2700*5697Smcpowers     /* Save sign for later, and take absolute value */
2701*5697Smcpowers     sgn = SIGN(&tmp); SIGN(&tmp) = ZPOS;
2702*5697Smcpowers 
2703*5697Smcpowers     /* Generate output digits in reverse order      */
2704*5697Smcpowers     while(mp_cmp_z(&tmp) != 0) {
2705*5697Smcpowers       if((res = mp_div_d(&tmp, rdx, &tmp, &rem)) != MP_OKAY) {
2706*5697Smcpowers 	mp_clear(&tmp);
2707*5697Smcpowers 	return res;
2708*5697Smcpowers       }
2709*5697Smcpowers 
2710*5697Smcpowers       /* Generate digits, use capital letters */
2711*5697Smcpowers       ch = s_mp_todigit(rem, radix, 0);
2712*5697Smcpowers 
2713*5697Smcpowers       str[pos++] = ch;
2714*5697Smcpowers     }
2715*5697Smcpowers 
2716*5697Smcpowers     /* Add - sign if original value was negative */
2717*5697Smcpowers     if(sgn == NEG)
2718*5697Smcpowers       str[pos++] = '-';
2719*5697Smcpowers 
2720*5697Smcpowers     /* Add trailing NUL to end the string        */
2721*5697Smcpowers     str[pos--] = '\0';
2722*5697Smcpowers 
2723*5697Smcpowers     /* Reverse the digits and sign indicator     */
2724*5697Smcpowers     ix = 0;
2725*5697Smcpowers     while(ix < pos) {
2726*5697Smcpowers       char tmp = str[ix];
2727*5697Smcpowers 
2728*5697Smcpowers       str[ix] = str[pos];
2729*5697Smcpowers       str[pos] = tmp;
2730*5697Smcpowers       ++ix;
2731*5697Smcpowers       --pos;
2732*5697Smcpowers     }
2733*5697Smcpowers 
2734*5697Smcpowers     mp_clear(&tmp);
2735*5697Smcpowers   }
2736*5697Smcpowers 
2737*5697Smcpowers   return MP_OKAY;
2738*5697Smcpowers 
2739*5697Smcpowers } /* end mp_toradix() */
2740*5697Smcpowers 
2741*5697Smcpowers /* }}} */
2742*5697Smcpowers 
2743*5697Smcpowers /* {{{ mp_tovalue(ch, r) */
2744*5697Smcpowers 
2745*5697Smcpowers int    mp_tovalue(char ch, int r)
2746*5697Smcpowers {
2747*5697Smcpowers   return s_mp_tovalue(ch, r);
2748*5697Smcpowers 
2749*5697Smcpowers } /* end mp_tovalue() */
2750*5697Smcpowers 
2751*5697Smcpowers /* }}} */
2752*5697Smcpowers 
2753*5697Smcpowers /* }}} */
2754*5697Smcpowers 
2755*5697Smcpowers /* {{{ mp_strerror(ec) */
2756*5697Smcpowers 
2757*5697Smcpowers /*
2758*5697Smcpowers   mp_strerror(ec)
2759*5697Smcpowers 
2760*5697Smcpowers   Return a string describing the meaning of error code 'ec'.  The
2761*5697Smcpowers   string returned is allocated in static memory, so the caller should
2762*5697Smcpowers   not attempt to modify or free the memory associated with this
2763*5697Smcpowers   string.
2764*5697Smcpowers  */
2765*5697Smcpowers const char  *mp_strerror(mp_err ec)
2766*5697Smcpowers {
2767*5697Smcpowers   int   aec = (ec < 0) ? -ec : ec;
2768*5697Smcpowers 
2769*5697Smcpowers   /* Code values are negative, so the senses of these comparisons
2770*5697Smcpowers      are accurate */
2771*5697Smcpowers   if(ec < MP_LAST_CODE || ec > MP_OKAY) {
2772*5697Smcpowers     return mp_err_string[0];  /* unknown error code */
2773*5697Smcpowers   } else {
2774*5697Smcpowers     return mp_err_string[aec + 1];
2775*5697Smcpowers   }
2776*5697Smcpowers 
2777*5697Smcpowers } /* end mp_strerror() */
2778*5697Smcpowers 
2779*5697Smcpowers /* }}} */
2780*5697Smcpowers 
2781*5697Smcpowers /*========================================================================*/
2782*5697Smcpowers /*------------------------------------------------------------------------*/
2783*5697Smcpowers /* Static function definitions (internal use only)                        */
2784*5697Smcpowers 
2785*5697Smcpowers /* {{{ Memory management */
2786*5697Smcpowers 
2787*5697Smcpowers /* {{{ s_mp_grow(mp, min) */
2788*5697Smcpowers 
2789*5697Smcpowers /* Make sure there are at least 'min' digits allocated to mp              */
2790*5697Smcpowers mp_err   s_mp_grow(mp_int *mp, mp_size min)
2791*5697Smcpowers {
2792*5697Smcpowers   if(min > ALLOC(mp)) {
2793*5697Smcpowers     mp_digit   *tmp;
2794*5697Smcpowers 
2795*5697Smcpowers     /* Set min to next nearest default precision block size */
2796*5697Smcpowers     min = MP_ROUNDUP(min, s_mp_defprec);
2797*5697Smcpowers 
2798*5697Smcpowers     if((tmp = s_mp_alloc(min, sizeof(mp_digit), FLAG(mp))) == NULL)
2799*5697Smcpowers       return MP_MEM;
2800*5697Smcpowers 
2801*5697Smcpowers     s_mp_copy(DIGITS(mp), tmp, USED(mp));
2802*5697Smcpowers 
2803*5697Smcpowers #if MP_CRYPTO
2804*5697Smcpowers     s_mp_setz(DIGITS(mp), ALLOC(mp));
2805*5697Smcpowers #endif
2806*5697Smcpowers     s_mp_free(DIGITS(mp), ALLOC(mp));
2807*5697Smcpowers     DIGITS(mp) = tmp;
2808*5697Smcpowers     ALLOC(mp) = min;
2809*5697Smcpowers   }
2810*5697Smcpowers 
2811*5697Smcpowers   return MP_OKAY;
2812*5697Smcpowers 
2813*5697Smcpowers } /* end s_mp_grow() */
2814*5697Smcpowers 
2815*5697Smcpowers /* }}} */
2816*5697Smcpowers 
2817*5697Smcpowers /* {{{ s_mp_pad(mp, min) */
2818*5697Smcpowers 
2819*5697Smcpowers /* Make sure the used size of mp is at least 'min', growing if needed     */
2820*5697Smcpowers mp_err   s_mp_pad(mp_int *mp, mp_size min)
2821*5697Smcpowers {
2822*5697Smcpowers   if(min > USED(mp)) {
2823*5697Smcpowers     mp_err  res;
2824*5697Smcpowers 
2825*5697Smcpowers     /* Make sure there is room to increase precision  */
2826*5697Smcpowers     if (min > ALLOC(mp)) {
2827*5697Smcpowers       if ((res = s_mp_grow(mp, min)) != MP_OKAY)
2828*5697Smcpowers 	return res;
2829*5697Smcpowers     } else {
2830*5697Smcpowers       s_mp_setz(DIGITS(mp) + USED(mp), min - USED(mp));
2831*5697Smcpowers     }
2832*5697Smcpowers 
2833*5697Smcpowers     /* Increase precision; should already be 0-filled */
2834*5697Smcpowers     USED(mp) = min;
2835*5697Smcpowers   }
2836*5697Smcpowers 
2837*5697Smcpowers   return MP_OKAY;
2838*5697Smcpowers 
2839*5697Smcpowers } /* end s_mp_pad() */
2840*5697Smcpowers 
2841*5697Smcpowers /* }}} */
2842*5697Smcpowers 
2843*5697Smcpowers /* {{{ s_mp_setz(dp, count) */
2844*5697Smcpowers 
2845*5697Smcpowers #if MP_MACRO == 0
2846*5697Smcpowers /* Set 'count' digits pointed to by dp to be zeroes                       */
2847*5697Smcpowers void s_mp_setz(mp_digit *dp, mp_size count)
2848*5697Smcpowers {
2849*5697Smcpowers #if MP_MEMSET == 0
2850*5697Smcpowers   int  ix;
2851*5697Smcpowers 
2852*5697Smcpowers   for(ix = 0; ix < count; ix++)
2853*5697Smcpowers     dp[ix] = 0;
2854*5697Smcpowers #else
2855*5697Smcpowers   memset(dp, 0, count * sizeof(mp_digit));
2856*5697Smcpowers #endif
2857*5697Smcpowers 
2858*5697Smcpowers } /* end s_mp_setz() */
2859*5697Smcpowers #endif
2860*5697Smcpowers 
2861*5697Smcpowers /* }}} */
2862*5697Smcpowers 
2863*5697Smcpowers /* {{{ s_mp_copy(sp, dp, count) */
2864*5697Smcpowers 
2865*5697Smcpowers #if MP_MACRO == 0
2866*5697Smcpowers /* Copy 'count' digits from sp to dp                                      */
2867*5697Smcpowers void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count)
2868*5697Smcpowers {
2869*5697Smcpowers #if MP_MEMCPY == 0
2870*5697Smcpowers   int  ix;
2871*5697Smcpowers 
2872*5697Smcpowers   for(ix = 0; ix < count; ix++)
2873*5697Smcpowers     dp[ix] = sp[ix];
2874*5697Smcpowers #else
2875*5697Smcpowers   memcpy(dp, sp, count * sizeof(mp_digit));
2876*5697Smcpowers #endif
2877*5697Smcpowers 
2878*5697Smcpowers } /* end s_mp_copy() */
2879*5697Smcpowers #endif
2880*5697Smcpowers 
2881*5697Smcpowers /* }}} */
2882*5697Smcpowers 
2883*5697Smcpowers /* {{{ s_mp_alloc(nb, ni, kmflag) */
2884*5697Smcpowers 
2885*5697Smcpowers #if MP_MACRO == 0
2886*5697Smcpowers /* Allocate ni records of nb bytes each, and return a pointer to that     */
2887*5697Smcpowers void    *s_mp_alloc(size_t nb, size_t ni, int kmflag)
2888*5697Smcpowers {
2889*5697Smcpowers   mp_int *mp;
2890*5697Smcpowers   ++mp_allocs;
2891*5697Smcpowers #ifdef _KERNEL
2892*5697Smcpowers   mp = kmem_zalloc(nb * ni, kmflag);
2893*5697Smcpowers   if (mp != NULL)
2894*5697Smcpowers     FLAG(mp) = kmflag;
2895*5697Smcpowers   return (mp);
2896*5697Smcpowers #else
2897*5697Smcpowers   return calloc(nb, ni);
2898*5697Smcpowers #endif
2899*5697Smcpowers 
2900*5697Smcpowers } /* end s_mp_alloc() */
2901*5697Smcpowers #endif
2902*5697Smcpowers 
2903*5697Smcpowers /* }}} */
2904*5697Smcpowers 
2905*5697Smcpowers /* {{{ s_mp_free(ptr) */
2906*5697Smcpowers 
2907*5697Smcpowers #if MP_MACRO == 0
2908*5697Smcpowers /* Free the memory pointed to by ptr                                      */
2909*5697Smcpowers void     s_mp_free(void *ptr, mp_size alloc)
2910*5697Smcpowers {
2911*5697Smcpowers   if(ptr) {
2912*5697Smcpowers     ++mp_frees;
2913*5697Smcpowers #ifdef _KERNEL
2914*5697Smcpowers     kmem_free(ptr, alloc * sizeof (mp_digit));
2915*5697Smcpowers #else
2916*5697Smcpowers     free(ptr);
2917*5697Smcpowers #endif
2918*5697Smcpowers   }
2919*5697Smcpowers } /* end s_mp_free() */
2920*5697Smcpowers #endif
2921*5697Smcpowers 
2922*5697Smcpowers /* }}} */
2923*5697Smcpowers 
2924*5697Smcpowers /* {{{ s_mp_clamp(mp) */
2925*5697Smcpowers 
2926*5697Smcpowers #if MP_MACRO == 0
2927*5697Smcpowers /* Remove leading zeroes from the given value                             */
2928*5697Smcpowers void     s_mp_clamp(mp_int *mp)
2929*5697Smcpowers {
2930*5697Smcpowers   mp_size used = MP_USED(mp);
2931*5697Smcpowers   while (used > 1 && DIGIT(mp, used - 1) == 0)
2932*5697Smcpowers     --used;
2933*5697Smcpowers   MP_USED(mp) = used;
2934*5697Smcpowers } /* end s_mp_clamp() */
2935*5697Smcpowers #endif
2936*5697Smcpowers 
2937*5697Smcpowers /* }}} */
2938*5697Smcpowers 
2939*5697Smcpowers /* {{{ s_mp_exch(a, b) */
2940*5697Smcpowers 
2941*5697Smcpowers /* Exchange the data for a and b; (b, a) = (a, b)                         */
2942*5697Smcpowers void     s_mp_exch(mp_int *a, mp_int *b)
2943*5697Smcpowers {
2944*5697Smcpowers   mp_int   tmp;
2945*5697Smcpowers 
2946*5697Smcpowers   tmp = *a;
2947*5697Smcpowers   *a = *b;
2948*5697Smcpowers   *b = tmp;
2949*5697Smcpowers 
2950*5697Smcpowers } /* end s_mp_exch() */
2951*5697Smcpowers 
2952*5697Smcpowers /* }}} */
2953*5697Smcpowers 
2954*5697Smcpowers /* }}} */
2955*5697Smcpowers 
2956*5697Smcpowers /* {{{ Arithmetic helpers */
2957*5697Smcpowers 
2958*5697Smcpowers /* {{{ s_mp_lshd(mp, p) */
2959*5697Smcpowers 
2960*5697Smcpowers /*
2961*5697Smcpowers    Shift mp leftward by p digits, growing if needed, and zero-filling
2962*5697Smcpowers    the in-shifted digits at the right end.  This is a convenient
2963*5697Smcpowers    alternative to multiplication by powers of the radix
2964*5697Smcpowers    The value of USED(mp) must already have been set to the value for
2965*5697Smcpowers    the shifted result.
2966*5697Smcpowers  */
2967*5697Smcpowers 
2968*5697Smcpowers mp_err   s_mp_lshd(mp_int *mp, mp_size p)
2969*5697Smcpowers {
2970*5697Smcpowers   mp_err  res;
2971*5697Smcpowers   mp_size pos;
2972*5697Smcpowers   int     ix;
2973*5697Smcpowers 
2974*5697Smcpowers   if(p == 0)
2975*5697Smcpowers     return MP_OKAY;
2976*5697Smcpowers 
2977*5697Smcpowers   if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0)
2978*5697Smcpowers     return MP_OKAY;
2979*5697Smcpowers 
2980*5697Smcpowers   if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
2981*5697Smcpowers     return res;
2982*5697Smcpowers 
2983*5697Smcpowers   pos = USED(mp) - 1;
2984*5697Smcpowers 
2985*5697Smcpowers   /* Shift all the significant figures over as needed */
2986*5697Smcpowers   for(ix = pos - p; ix >= 0; ix--)
2987*5697Smcpowers     DIGIT(mp, ix + p) = DIGIT(mp, ix);
2988*5697Smcpowers 
2989*5697Smcpowers   /* Fill the bottom digits with zeroes */
2990*5697Smcpowers   for(ix = 0; ix < p; ix++)
2991*5697Smcpowers     DIGIT(mp, ix) = 0;
2992*5697Smcpowers 
2993*5697Smcpowers   return MP_OKAY;
2994*5697Smcpowers 
2995*5697Smcpowers } /* end s_mp_lshd() */
2996*5697Smcpowers 
2997*5697Smcpowers /* }}} */
2998*5697Smcpowers 
2999*5697Smcpowers /* {{{ s_mp_mul_2d(mp, d) */
3000*5697Smcpowers 
3001*5697Smcpowers /*
3002*5697Smcpowers   Multiply the integer by 2^d, where d is a number of bits.  This
3003*5697Smcpowers   amounts to a bitwise shift of the value.
3004*5697Smcpowers  */
3005*5697Smcpowers mp_err   s_mp_mul_2d(mp_int *mp, mp_digit d)
3006*5697Smcpowers {
3007*5697Smcpowers   mp_err   res;
3008*5697Smcpowers   mp_digit dshift, bshift;
3009*5697Smcpowers   mp_digit mask;
3010*5697Smcpowers 
3011*5697Smcpowers   ARGCHK(mp != NULL,  MP_BADARG);
3012*5697Smcpowers 
3013*5697Smcpowers   dshift = d / MP_DIGIT_BIT;
3014*5697Smcpowers   bshift = d % MP_DIGIT_BIT;
3015*5697Smcpowers   /* bits to be shifted out of the top word */
3016*5697Smcpowers   mask   = ((mp_digit)~0 << (MP_DIGIT_BIT - bshift));
3017*5697Smcpowers   mask  &= MP_DIGIT(mp, MP_USED(mp) - 1);
3018*5697Smcpowers 
3019*5697Smcpowers   if (MP_OKAY != (res = s_mp_pad(mp, MP_USED(mp) + dshift + (mask != 0) )))
3020*5697Smcpowers     return res;
3021*5697Smcpowers 
3022*5697Smcpowers   if (dshift && MP_OKAY != (res = s_mp_lshd(mp, dshift)))
3023*5697Smcpowers     return res;
3024*5697Smcpowers 
3025*5697Smcpowers   if (bshift) {
3026*5697Smcpowers     mp_digit *pa = MP_DIGITS(mp);
3027*5697Smcpowers     mp_digit *alim = pa + MP_USED(mp);
3028*5697Smcpowers     mp_digit  prev = 0;
3029*5697Smcpowers 
3030*5697Smcpowers     for (pa += dshift; pa < alim; ) {
3031*5697Smcpowers       mp_digit x = *pa;
3032*5697Smcpowers       *pa++ = (x << bshift) | prev;
3033*5697Smcpowers       prev = x >> (DIGIT_BIT - bshift);
3034*5697Smcpowers     }
3035*5697Smcpowers   }
3036*5697Smcpowers 
3037*5697Smcpowers   s_mp_clamp(mp);
3038*5697Smcpowers   return MP_OKAY;
3039*5697Smcpowers } /* end s_mp_mul_2d() */
3040*5697Smcpowers 
3041*5697Smcpowers /* {{{ s_mp_rshd(mp, p) */
3042*5697Smcpowers 
3043*5697Smcpowers /*
3044*5697Smcpowers    Shift mp rightward by p digits.  Maintains the invariant that
3045*5697Smcpowers    digits above the precision are all zero.  Digits shifted off the
3046*5697Smcpowers    end are lost.  Cannot fail.
3047*5697Smcpowers  */
3048*5697Smcpowers 
3049*5697Smcpowers void     s_mp_rshd(mp_int *mp, mp_size p)
3050*5697Smcpowers {
3051*5697Smcpowers   mp_size  ix;
3052*5697Smcpowers   mp_digit *src, *dst;
3053*5697Smcpowers 
3054*5697Smcpowers   if(p == 0)
3055*5697Smcpowers     return;
3056*5697Smcpowers 
3057*5697Smcpowers   /* Shortcut when all digits are to be shifted off */
3058*5697Smcpowers   if(p >= USED(mp)) {
3059*5697Smcpowers     s_mp_setz(DIGITS(mp), ALLOC(mp));
3060*5697Smcpowers     USED(mp) = 1;
3061*5697Smcpowers     SIGN(mp) = ZPOS;
3062*5697Smcpowers     return;
3063*5697Smcpowers   }
3064*5697Smcpowers 
3065*5697Smcpowers   /* Shift all the significant figures over as needed */
3066*5697Smcpowers   dst = MP_DIGITS(mp);
3067*5697Smcpowers   src = dst + p;
3068*5697Smcpowers   for (ix = USED(mp) - p; ix > 0; ix--)
3069*5697Smcpowers     *dst++ = *src++;
3070*5697Smcpowers 
3071*5697Smcpowers   MP_USED(mp) -= p;
3072*5697Smcpowers   /* Fill the top digits with zeroes */
3073*5697Smcpowers   while (p-- > 0)
3074*5697Smcpowers     *dst++ = 0;
3075*5697Smcpowers 
3076*5697Smcpowers #if 0
3077*5697Smcpowers   /* Strip off any leading zeroes    */
3078*5697Smcpowers   s_mp_clamp(mp);
3079*5697Smcpowers #endif
3080*5697Smcpowers 
3081*5697Smcpowers } /* end s_mp_rshd() */
3082*5697Smcpowers 
3083*5697Smcpowers /* }}} */
3084*5697Smcpowers 
3085*5697Smcpowers /* {{{ s_mp_div_2(mp) */
3086*5697Smcpowers 
3087*5697Smcpowers /* Divide by two -- take advantage of radix properties to do it fast      */
3088*5697Smcpowers void     s_mp_div_2(mp_int *mp)
3089*5697Smcpowers {
3090*5697Smcpowers   s_mp_div_2d(mp, 1);
3091*5697Smcpowers 
3092*5697Smcpowers } /* end s_mp_div_2() */
3093*5697Smcpowers 
3094*5697Smcpowers /* }}} */
3095*5697Smcpowers 
3096*5697Smcpowers /* {{{ s_mp_mul_2(mp) */
3097*5697Smcpowers 
3098*5697Smcpowers mp_err s_mp_mul_2(mp_int *mp)
3099*5697Smcpowers {
3100*5697Smcpowers   mp_digit *pd;
3101*5697Smcpowers   int      ix, used;
3102*5697Smcpowers   mp_digit kin = 0;
3103*5697Smcpowers 
3104*5697Smcpowers   /* Shift digits leftward by 1 bit */
3105*5697Smcpowers   used = MP_USED(mp);
3106*5697Smcpowers   pd = MP_DIGITS(mp);
3107*5697Smcpowers   for (ix = 0; ix < used; ix++) {
3108*5697Smcpowers     mp_digit d = *pd;
3109*5697Smcpowers     *pd++ = (d << 1) | kin;
3110*5697Smcpowers     kin = (d >> (DIGIT_BIT - 1));
3111*5697Smcpowers   }
3112*5697Smcpowers 
3113*5697Smcpowers   /* Deal with rollover from last digit */
3114*5697Smcpowers   if (kin) {
3115*5697Smcpowers     if (ix >= ALLOC(mp)) {
3116*5697Smcpowers       mp_err res;
3117*5697Smcpowers       if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)
3118*5697Smcpowers 	return res;
3119*5697Smcpowers     }
3120*5697Smcpowers 
3121*5697Smcpowers     DIGIT(mp, ix) = kin;
3122*5697Smcpowers     USED(mp) += 1;
3123*5697Smcpowers   }
3124*5697Smcpowers 
3125*5697Smcpowers   return MP_OKAY;
3126*5697Smcpowers 
3127*5697Smcpowers } /* end s_mp_mul_2() */
3128*5697Smcpowers 
3129*5697Smcpowers /* }}} */
3130*5697Smcpowers 
3131*5697Smcpowers /* {{{ s_mp_mod_2d(mp, d) */
3132*5697Smcpowers 
3133*5697Smcpowers /*
3134*5697Smcpowers   Remainder the integer by 2^d, where d is a number of bits.  This
3135*5697Smcpowers   amounts to a bitwise AND of the value, and does not require the full
3136*5697Smcpowers   division code
3137*5697Smcpowers  */
3138*5697Smcpowers void     s_mp_mod_2d(mp_int *mp, mp_digit d)
3139*5697Smcpowers {
3140*5697Smcpowers   mp_size  ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
3141*5697Smcpowers   mp_size  ix;
3142*5697Smcpowers   mp_digit dmask;
3143*5697Smcpowers 
3144*5697Smcpowers   if(ndig >= USED(mp))
3145*5697Smcpowers     return;
3146*5697Smcpowers 
3147*5697Smcpowers   /* Flush all the bits above 2^d in its digit */
3148*5697Smcpowers   dmask = ((mp_digit)1 << nbit) - 1;
3149*5697Smcpowers   DIGIT(mp, ndig) &= dmask;
3150*5697Smcpowers 
3151*5697Smcpowers   /* Flush all digits above the one with 2^d in it */
3152*5697Smcpowers   for(ix = ndig + 1; ix < USED(mp); ix++)
3153*5697Smcpowers     DIGIT(mp, ix) = 0;
3154*5697Smcpowers 
3155*5697Smcpowers   s_mp_clamp(mp);
3156*5697Smcpowers 
3157*5697Smcpowers } /* end s_mp_mod_2d() */
3158*5697Smcpowers 
3159*5697Smcpowers /* }}} */
3160*5697Smcpowers 
3161*5697Smcpowers /* {{{ s_mp_div_2d(mp, d) */
3162*5697Smcpowers 
3163*5697Smcpowers /*
3164*5697Smcpowers   Divide the integer by 2^d, where d is a number of bits.  This
3165*5697Smcpowers   amounts to a bitwise shift of the value, and does not require the
3166*5697Smcpowers   full division code (used in Barrett reduction, see below)
3167*5697Smcpowers  */
3168*5697Smcpowers void     s_mp_div_2d(mp_int *mp, mp_digit d)
3169*5697Smcpowers {
3170*5697Smcpowers   int       ix;
3171*5697Smcpowers   mp_digit  save, next, mask;
3172*5697Smcpowers 
3173*5697Smcpowers   s_mp_rshd(mp, d / DIGIT_BIT);
3174*5697Smcpowers   d %= DIGIT_BIT;
3175*5697Smcpowers   if (d) {
3176*5697Smcpowers     mask = ((mp_digit)1 << d) - 1;
3177*5697Smcpowers     save = 0;
3178*5697Smcpowers     for(ix = USED(mp) - 1; ix >= 0; ix--) {
3179*5697Smcpowers       next = DIGIT(mp, ix) & mask;
3180*5697Smcpowers       DIGIT(mp, ix) = (DIGIT(mp, ix) >> d) | (save << (DIGIT_BIT - d));
3181*5697Smcpowers       save = next;
3182*5697Smcpowers     }
3183*5697Smcpowers   }
3184*5697Smcpowers   s_mp_clamp(mp);
3185*5697Smcpowers 
3186*5697Smcpowers } /* end s_mp_div_2d() */
3187*5697Smcpowers 
3188*5697Smcpowers /* }}} */
3189*5697Smcpowers 
3190*5697Smcpowers /* {{{ s_mp_norm(a, b, *d) */
3191*5697Smcpowers 
3192*5697Smcpowers /*
3193*5697Smcpowers   s_mp_norm(a, b, *d)
3194*5697Smcpowers 
3195*5697Smcpowers   Normalize a and b for division, where b is the divisor.  In order
3196*5697Smcpowers   that we might make good guesses for quotient digits, we want the
3197*5697Smcpowers   leading digit of b to be at least half the radix, which we
3198*5697Smcpowers   accomplish by multiplying a and b by a power of 2.  The exponent
3199*5697Smcpowers   (shift count) is placed in *pd, so that the remainder can be shifted
3200*5697Smcpowers   back at the end of the division process.
3201*5697Smcpowers  */
3202*5697Smcpowers 
3203*5697Smcpowers mp_err   s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd)
3204*5697Smcpowers {
3205*5697Smcpowers   mp_digit  d;
3206*5697Smcpowers   mp_digit  mask;
3207*5697Smcpowers   mp_digit  b_msd;
3208*5697Smcpowers   mp_err    res    = MP_OKAY;
3209*5697Smcpowers 
3210*5697Smcpowers   d = 0;
3211*5697Smcpowers   mask  = DIGIT_MAX & ~(DIGIT_MAX >> 1);	/* mask is msb of digit */
3212*5697Smcpowers   b_msd = DIGIT(b, USED(b) - 1);
3213*5697Smcpowers   while (!(b_msd & mask)) {
3214*5697Smcpowers     b_msd <<= 1;
3215*5697Smcpowers     ++d;
3216*5697Smcpowers   }
3217*5697Smcpowers 
3218*5697Smcpowers   if (d) {
3219*5697Smcpowers     MP_CHECKOK( s_mp_mul_2d(a, d) );
3220*5697Smcpowers     MP_CHECKOK( s_mp_mul_2d(b, d) );
3221*5697Smcpowers   }
3222*5697Smcpowers 
3223*5697Smcpowers   *pd = d;
3224*5697Smcpowers CLEANUP:
3225*5697Smcpowers   return res;
3226*5697Smcpowers 
3227*5697Smcpowers } /* end s_mp_norm() */
3228*5697Smcpowers 
3229*5697Smcpowers /* }}} */
3230*5697Smcpowers 
3231*5697Smcpowers /* }}} */
3232*5697Smcpowers 
3233*5697Smcpowers /* {{{ Primitive digit arithmetic */
3234*5697Smcpowers 
3235*5697Smcpowers /* {{{ s_mp_add_d(mp, d) */
3236*5697Smcpowers 
3237*5697Smcpowers /* Add d to |mp| in place                                                 */
3238*5697Smcpowers mp_err   s_mp_add_d(mp_int *mp, mp_digit d)    /* unsigned digit addition */
3239*5697Smcpowers {
3240*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3241*5697Smcpowers   mp_word   w, k = 0;
3242*5697Smcpowers   mp_size   ix = 1;
3243*5697Smcpowers 
3244*5697Smcpowers   w = (mp_word)DIGIT(mp, 0) + d;
3245*5697Smcpowers   DIGIT(mp, 0) = ACCUM(w);
3246*5697Smcpowers   k = CARRYOUT(w);
3247*5697Smcpowers 
3248*5697Smcpowers   while(ix < USED(mp) && k) {
3249*5697Smcpowers     w = (mp_word)DIGIT(mp, ix) + k;
3250*5697Smcpowers     DIGIT(mp, ix) = ACCUM(w);
3251*5697Smcpowers     k = CARRYOUT(w);
3252*5697Smcpowers     ++ix;
3253*5697Smcpowers   }
3254*5697Smcpowers 
3255*5697Smcpowers   if(k != 0) {
3256*5697Smcpowers     mp_err  res;
3257*5697Smcpowers 
3258*5697Smcpowers     if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
3259*5697Smcpowers       return res;
3260*5697Smcpowers 
3261*5697Smcpowers     DIGIT(mp, ix) = (mp_digit)k;
3262*5697Smcpowers   }
3263*5697Smcpowers 
3264*5697Smcpowers   return MP_OKAY;
3265*5697Smcpowers #else
3266*5697Smcpowers   mp_digit * pmp = MP_DIGITS(mp);
3267*5697Smcpowers   mp_digit sum, mp_i, carry = 0;
3268*5697Smcpowers   mp_err   res = MP_OKAY;
3269*5697Smcpowers   int used = (int)MP_USED(mp);
3270*5697Smcpowers 
3271*5697Smcpowers   mp_i = *pmp;
3272*5697Smcpowers   *pmp++ = sum = d + mp_i;
3273*5697Smcpowers   carry = (sum < d);
3274*5697Smcpowers   while (carry && --used > 0) {
3275*5697Smcpowers     mp_i = *pmp;
3276*5697Smcpowers     *pmp++ = sum = carry + mp_i;
3277*5697Smcpowers     carry = !sum;
3278*5697Smcpowers   }
3279*5697Smcpowers   if (carry && !used) {
3280*5697Smcpowers     /* mp is growing */
3281*5697Smcpowers     used = MP_USED(mp);
3282*5697Smcpowers     MP_CHECKOK( s_mp_pad(mp, used + 1) );
3283*5697Smcpowers     MP_DIGIT(mp, used) = carry;
3284*5697Smcpowers   }
3285*5697Smcpowers CLEANUP:
3286*5697Smcpowers   return res;
3287*5697Smcpowers #endif
3288*5697Smcpowers } /* end s_mp_add_d() */
3289*5697Smcpowers 
3290*5697Smcpowers /* }}} */
3291*5697Smcpowers 
3292*5697Smcpowers /* {{{ s_mp_sub_d(mp, d) */
3293*5697Smcpowers 
3294*5697Smcpowers /* Subtract d from |mp| in place, assumes |mp| > d                        */
3295*5697Smcpowers mp_err   s_mp_sub_d(mp_int *mp, mp_digit d)    /* unsigned digit subtract */
3296*5697Smcpowers {
3297*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
3298*5697Smcpowers   mp_word   w, b = 0;
3299*5697Smcpowers   mp_size   ix = 1;
3300*5697Smcpowers 
3301*5697Smcpowers   /* Compute initial subtraction    */
3302*5697Smcpowers   w = (RADIX + (mp_word)DIGIT(mp, 0)) - d;
3303*5697Smcpowers   b = CARRYOUT(w) ? 0 : 1;
3304*5697Smcpowers   DIGIT(mp, 0) = ACCUM(w);
3305*5697Smcpowers 
3306*5697Smcpowers   /* Propagate borrows leftward     */
3307*5697Smcpowers   while(b && ix < USED(mp)) {
3308*5697Smcpowers     w = (RADIX + (mp_word)DIGIT(mp, ix)) - b;
3309*5697Smcpowers     b = CARRYOUT(w) ? 0 : 1;
3310*5697Smcpowers     DIGIT(mp, ix) = ACCUM(w);
3311*5697Smcpowers     ++ix;
3312*5697Smcpowers   }
3313*5697Smcpowers 
3314*5697Smcpowers   /* Remove leading zeroes          */
3315*5697Smcpowers   s_mp_clamp(mp);
3316*5697Smcpowers 
3317*5697Smcpowers   /* If we have a borrow out, it's a violation of the input invariant */
3318*5697Smcpowers   if(b)
3319*5697Smcpowers     return MP_RANGE;
3320*5697Smcpowers   else
3321*5697Smcpowers     return MP_OKAY;
3322*5697Smcpowers #else
3323*5697Smcpowers   mp_digit *pmp = MP_DIGITS(mp);
3324*5697Smcpowers   mp_digit mp_i, diff, borrow;
3325*5697Smcpowers   mp_size  used = MP_USED(mp);
3326*5697Smcpowers 
3327*5697Smcpowers   mp_i = *pmp;
3328*5697Smcpowers   *pmp++ = diff = mp_i - d;
3329*5697Smcpowers   borrow = (diff > mp_i);
3330*5697Smcpowers   while (borrow && --used) {
3331*5697Smcpowers     mp_i = *pmp;
3332*5697Smcpowers     *pmp++ = diff = mp_i - borrow;
3333*5697Smcpowers     borrow = (diff > mp_i);
3334*5697Smcpowers   }
3335*5697Smcpowers   s_mp_clamp(mp);
3336*5697Smcpowers   return (borrow && !used) ? MP_RANGE : MP_OKAY;
3337*5697Smcpowers #endif
3338*5697Smcpowers } /* end s_mp_sub_d() */
3339*5697Smcpowers 
3340*5697Smcpowers /* }}} */
3341*5697Smcpowers 
3342*5697Smcpowers /* {{{ s_mp_mul_d(a, d) */
3343*5697Smcpowers 
3344*5697Smcpowers /* Compute a = a * d, single digit multiplication                         */
3345*5697Smcpowers mp_err   s_mp_mul_d(mp_int *a, mp_digit d)
3346*5697Smcpowers {
3347*5697Smcpowers   mp_err  res;
3348*5697Smcpowers   mp_size used;
3349*5697Smcpowers   int     pow;
3350*5697Smcpowers 
3351*5697Smcpowers   if (!d) {
3352*5697Smcpowers     mp_zero(a);
3353*5697Smcpowers     return MP_OKAY;
3354*5697Smcpowers   }
3355*5697Smcpowers   if (d == 1)
3356*5697Smcpowers     return MP_OKAY;
3357*5697Smcpowers   if (0 <= (pow = s_mp_ispow2d(d))) {
3358*5697Smcpowers     return s_mp_mul_2d(a, (mp_digit)pow);
3359*5697Smcpowers   }
3360*5697Smcpowers 
3361*5697Smcpowers   used = MP_USED(a);
3362*5697Smcpowers   MP_CHECKOK( s_mp_pad(a, used + 1) );
3363*5697Smcpowers 
3364*5697Smcpowers   s_mpv_mul_d(MP_DIGITS(a), used, d, MP_DIGITS(a));
3365*5697Smcpowers 
3366*5697Smcpowers   s_mp_clamp(a);
3367*5697Smcpowers 
3368*5697Smcpowers CLEANUP:
3369*5697Smcpowers   return res;
3370*5697Smcpowers 
3371*5697Smcpowers } /* end s_mp_mul_d() */
3372*5697Smcpowers 
3373*5697Smcpowers /* }}} */
3374*5697Smcpowers 
3375*5697Smcpowers /* {{{ s_mp_div_d(mp, d, r) */
3376*5697Smcpowers 
3377*5697Smcpowers /*
3378*5697Smcpowers   s_mp_div_d(mp, d, r)
3379*5697Smcpowers 
3380*5697Smcpowers   Compute the quotient mp = mp / d and remainder r = mp mod d, for a
3381*5697Smcpowers   single digit d.  If r is null, the remainder will be discarded.
3382*5697Smcpowers  */
3383*5697Smcpowers 
3384*5697Smcpowers mp_err   s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
3385*5697Smcpowers {
3386*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
3387*5697Smcpowers   mp_word   w = 0, q;
3388*5697Smcpowers #else
3389*5697Smcpowers   mp_digit  w, q;
3390*5697Smcpowers #endif
3391*5697Smcpowers   int       ix;
3392*5697Smcpowers   mp_err    res;
3393*5697Smcpowers   mp_int    quot;
3394*5697Smcpowers   mp_int    rem;
3395*5697Smcpowers 
3396*5697Smcpowers   if(d == 0)
3397*5697Smcpowers     return MP_RANGE;
3398*5697Smcpowers   if (d == 1) {
3399*5697Smcpowers     if (r)
3400*5697Smcpowers       *r = 0;
3401*5697Smcpowers     return MP_OKAY;
3402*5697Smcpowers   }
3403*5697Smcpowers   /* could check for power of 2 here, but mp_div_d does that. */
3404*5697Smcpowers   if (MP_USED(mp) == 1) {
3405*5697Smcpowers     mp_digit n   = MP_DIGIT(mp,0);
3406*5697Smcpowers     mp_digit rem;
3407*5697Smcpowers 
3408*5697Smcpowers     q   = n / d;
3409*5697Smcpowers     rem = n % d;
3410*5697Smcpowers     MP_DIGIT(mp,0) = q;
3411*5697Smcpowers     if (r)
3412*5697Smcpowers       *r = rem;
3413*5697Smcpowers     return MP_OKAY;
3414*5697Smcpowers   }
3415*5697Smcpowers 
3416*5697Smcpowers   MP_DIGITS(&rem)  = 0;
3417*5697Smcpowers   MP_DIGITS(&quot) = 0;
3418*5697Smcpowers   /* Make room for the quotient */
3419*5697Smcpowers   MP_CHECKOK( mp_init_size(&quot, USED(mp), FLAG(mp)) );
3420*5697Smcpowers 
3421*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
3422*5697Smcpowers   for(ix = USED(mp) - 1; ix >= 0; ix--) {
3423*5697Smcpowers     w = (w << DIGIT_BIT) | DIGIT(mp, ix);
3424*5697Smcpowers 
3425*5697Smcpowers     if(w >= d) {
3426*5697Smcpowers       q = w / d;
3427*5697Smcpowers       w = w % d;
3428*5697Smcpowers     } else {
3429*5697Smcpowers       q = 0;
3430*5697Smcpowers     }
3431*5697Smcpowers 
3432*5697Smcpowers     s_mp_lshd(&quot, 1);
3433*5697Smcpowers     DIGIT(&quot, 0) = (mp_digit)q;
3434*5697Smcpowers   }
3435*5697Smcpowers #else
3436*5697Smcpowers   {
3437*5697Smcpowers     mp_digit p;
3438*5697Smcpowers #if !defined(MP_ASSEMBLY_DIV_2DX1D)
3439*5697Smcpowers     mp_digit norm;
3440*5697Smcpowers #endif
3441*5697Smcpowers 
3442*5697Smcpowers     MP_CHECKOK( mp_init_copy(&rem, mp) );
3443*5697Smcpowers 
3444*5697Smcpowers #if !defined(MP_ASSEMBLY_DIV_2DX1D)
3445*5697Smcpowers     MP_DIGIT(&quot, 0) = d;
3446*5697Smcpowers     MP_CHECKOK( s_mp_norm(&rem, &quot, &norm) );
3447*5697Smcpowers     if (norm)
3448*5697Smcpowers       d <<= norm;
3449*5697Smcpowers     MP_DIGIT(&quot, 0) = 0;
3450*5697Smcpowers #endif
3451*5697Smcpowers 
3452*5697Smcpowers     p = 0;
3453*5697Smcpowers     for (ix = USED(&rem) - 1; ix >= 0; ix--) {
3454*5697Smcpowers       w = DIGIT(&rem, ix);
3455*5697Smcpowers 
3456*5697Smcpowers       if (p) {
3457*5697Smcpowers         MP_CHECKOK( s_mpv_div_2dx1d(p, w, d, &q, &w) );
3458*5697Smcpowers       } else if (w >= d) {
3459*5697Smcpowers 	q = w / d;
3460*5697Smcpowers 	w = w % d;
3461*5697Smcpowers       } else {
3462*5697Smcpowers 	q = 0;
3463*5697Smcpowers       }
3464*5697Smcpowers 
3465*5697Smcpowers       MP_CHECKOK( s_mp_lshd(&quot, 1) );
3466*5697Smcpowers       DIGIT(&quot, 0) = q;
3467*5697Smcpowers       p = w;
3468*5697Smcpowers     }
3469*5697Smcpowers #if !defined(MP_ASSEMBLY_DIV_2DX1D)
3470*5697Smcpowers     if (norm)
3471*5697Smcpowers       w >>= norm;
3472*5697Smcpowers #endif
3473*5697Smcpowers   }
3474*5697Smcpowers #endif
3475*5697Smcpowers 
3476*5697Smcpowers   /* Deliver the remainder, if desired */
3477*5697Smcpowers   if(r)
3478*5697Smcpowers     *r = (mp_digit)w;
3479*5697Smcpowers 
3480*5697Smcpowers   s_mp_clamp(&quot);
3481*5697Smcpowers   mp_exch(&quot, mp);
3482*5697Smcpowers CLEANUP:
3483*5697Smcpowers   mp_clear(&quot);
3484*5697Smcpowers   mp_clear(&rem);
3485*5697Smcpowers 
3486*5697Smcpowers   return res;
3487*5697Smcpowers } /* end s_mp_div_d() */
3488*5697Smcpowers 
3489*5697Smcpowers /* }}} */
3490*5697Smcpowers 
3491*5697Smcpowers 
3492*5697Smcpowers /* }}} */
3493*5697Smcpowers 
3494*5697Smcpowers /* {{{ Primitive full arithmetic */
3495*5697Smcpowers 
3496*5697Smcpowers /* {{{ s_mp_add(a, b) */
3497*5697Smcpowers 
3498*5697Smcpowers /* Compute a = |a| + |b|                                                  */
3499*5697Smcpowers mp_err   s_mp_add(mp_int *a, const mp_int *b)  /* magnitude addition      */
3500*5697Smcpowers {
3501*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3502*5697Smcpowers   mp_word   w = 0;
3503*5697Smcpowers #else
3504*5697Smcpowers   mp_digit  d, sum, carry = 0;
3505*5697Smcpowers #endif
3506*5697Smcpowers   mp_digit *pa, *pb;
3507*5697Smcpowers   mp_size   ix;
3508*5697Smcpowers   mp_size   used;
3509*5697Smcpowers   mp_err    res;
3510*5697Smcpowers 
3511*5697Smcpowers   /* Make sure a has enough precision for the output value */
3512*5697Smcpowers   if((USED(b) > USED(a)) && (res = s_mp_pad(a, USED(b))) != MP_OKAY)
3513*5697Smcpowers     return res;
3514*5697Smcpowers 
3515*5697Smcpowers   /*
3516*5697Smcpowers     Add up all digits up to the precision of b.  If b had initially
3517*5697Smcpowers     the same precision as a, or greater, we took care of it by the
3518*5697Smcpowers     padding step above, so there is no problem.  If b had initially
3519*5697Smcpowers     less precision, we'll have to make sure the carry out is duly
3520*5697Smcpowers     propagated upward among the higher-order digits of the sum.
3521*5697Smcpowers    */
3522*5697Smcpowers   pa = MP_DIGITS(a);
3523*5697Smcpowers   pb = MP_DIGITS(b);
3524*5697Smcpowers   used = MP_USED(b);
3525*5697Smcpowers   for(ix = 0; ix < used; ix++) {
3526*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3527*5697Smcpowers     w = w + *pa + *pb++;
3528*5697Smcpowers     *pa++ = ACCUM(w);
3529*5697Smcpowers     w = CARRYOUT(w);
3530*5697Smcpowers #else
3531*5697Smcpowers     d = *pa;
3532*5697Smcpowers     sum = d + *pb++;
3533*5697Smcpowers     d = (sum < d);			/* detect overflow */
3534*5697Smcpowers     *pa++ = sum += carry;
3535*5697Smcpowers     carry = d + (sum < carry);		/* detect overflow */
3536*5697Smcpowers #endif
3537*5697Smcpowers   }
3538*5697Smcpowers 
3539*5697Smcpowers   /* If we run out of 'b' digits before we're actually done, make
3540*5697Smcpowers      sure the carries get propagated upward...
3541*5697Smcpowers    */
3542*5697Smcpowers   used = MP_USED(a);
3543*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3544*5697Smcpowers   while (w && ix < used) {
3545*5697Smcpowers     w = w + *pa;
3546*5697Smcpowers     *pa++ = ACCUM(w);
3547*5697Smcpowers     w = CARRYOUT(w);
3548*5697Smcpowers     ++ix;
3549*5697Smcpowers   }
3550*5697Smcpowers #else
3551*5697Smcpowers   while (carry && ix < used) {
3552*5697Smcpowers     sum = carry + *pa;
3553*5697Smcpowers     *pa++ = sum;
3554*5697Smcpowers     carry = !sum;
3555*5697Smcpowers     ++ix;
3556*5697Smcpowers   }
3557*5697Smcpowers #endif
3558*5697Smcpowers 
3559*5697Smcpowers   /* If there's an overall carry out, increase precision and include
3560*5697Smcpowers      it.  We could have done this initially, but why touch the memory
3561*5697Smcpowers      allocator unless we're sure we have to?
3562*5697Smcpowers    */
3563*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3564*5697Smcpowers   if (w) {
3565*5697Smcpowers     if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
3566*5697Smcpowers       return res;
3567*5697Smcpowers 
3568*5697Smcpowers     DIGIT(a, ix) = (mp_digit)w;
3569*5697Smcpowers   }
3570*5697Smcpowers #else
3571*5697Smcpowers   if (carry) {
3572*5697Smcpowers     if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
3573*5697Smcpowers       return res;
3574*5697Smcpowers 
3575*5697Smcpowers     DIGIT(a, used) = carry;
3576*5697Smcpowers   }
3577*5697Smcpowers #endif
3578*5697Smcpowers 
3579*5697Smcpowers   return MP_OKAY;
3580*5697Smcpowers } /* end s_mp_add() */
3581*5697Smcpowers 
3582*5697Smcpowers /* }}} */
3583*5697Smcpowers 
3584*5697Smcpowers /* Compute c = |a| + |b|         */ /* magnitude addition      */
3585*5697Smcpowers mp_err   s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c)
3586*5697Smcpowers {
3587*5697Smcpowers   mp_digit *pa, *pb, *pc;
3588*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3589*5697Smcpowers   mp_word   w = 0;
3590*5697Smcpowers #else
3591*5697Smcpowers   mp_digit  sum, carry = 0, d;
3592*5697Smcpowers #endif
3593*5697Smcpowers   mp_size   ix;
3594*5697Smcpowers   mp_size   used;
3595*5697Smcpowers   mp_err    res;
3596*5697Smcpowers 
3597*5697Smcpowers   MP_SIGN(c) = MP_SIGN(a);
3598*5697Smcpowers   if (MP_USED(a) < MP_USED(b)) {
3599*5697Smcpowers     const mp_int *xch = a;
3600*5697Smcpowers     a = b;
3601*5697Smcpowers     b = xch;
3602*5697Smcpowers   }
3603*5697Smcpowers 
3604*5697Smcpowers   /* Make sure a has enough precision for the output value */
3605*5697Smcpowers   if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
3606*5697Smcpowers     return res;
3607*5697Smcpowers 
3608*5697Smcpowers   /*
3609*5697Smcpowers     Add up all digits up to the precision of b.  If b had initially
3610*5697Smcpowers     the same precision as a, or greater, we took care of it by the
3611*5697Smcpowers     exchange step above, so there is no problem.  If b had initially
3612*5697Smcpowers     less precision, we'll have to make sure the carry out is duly
3613*5697Smcpowers     propagated upward among the higher-order digits of the sum.
3614*5697Smcpowers    */
3615*5697Smcpowers   pa = MP_DIGITS(a);
3616*5697Smcpowers   pb = MP_DIGITS(b);
3617*5697Smcpowers   pc = MP_DIGITS(c);
3618*5697Smcpowers   used = MP_USED(b);
3619*5697Smcpowers   for (ix = 0; ix < used; ix++) {
3620*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3621*5697Smcpowers     w = w + *pa++ + *pb++;
3622*5697Smcpowers     *pc++ = ACCUM(w);
3623*5697Smcpowers     w = CARRYOUT(w);
3624*5697Smcpowers #else
3625*5697Smcpowers     d = *pa++;
3626*5697Smcpowers     sum = d + *pb++;
3627*5697Smcpowers     d = (sum < d);			/* detect overflow */
3628*5697Smcpowers     *pc++ = sum += carry;
3629*5697Smcpowers     carry = d + (sum < carry);		/* detect overflow */
3630*5697Smcpowers #endif
3631*5697Smcpowers   }
3632*5697Smcpowers 
3633*5697Smcpowers   /* If we run out of 'b' digits before we're actually done, make
3634*5697Smcpowers      sure the carries get propagated upward...
3635*5697Smcpowers    */
3636*5697Smcpowers   for (used = MP_USED(a); ix < used; ++ix) {
3637*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3638*5697Smcpowers     w = w + *pa++;
3639*5697Smcpowers     *pc++ = ACCUM(w);
3640*5697Smcpowers     w = CARRYOUT(w);
3641*5697Smcpowers #else
3642*5697Smcpowers     *pc++ = sum = carry + *pa++;
3643*5697Smcpowers     carry = (sum < carry);
3644*5697Smcpowers #endif
3645*5697Smcpowers   }
3646*5697Smcpowers 
3647*5697Smcpowers   /* If there's an overall carry out, increase precision and include
3648*5697Smcpowers      it.  We could have done this initially, but why touch the memory
3649*5697Smcpowers      allocator unless we're sure we have to?
3650*5697Smcpowers    */
3651*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3652*5697Smcpowers   if (w) {
3653*5697Smcpowers     if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
3654*5697Smcpowers       return res;
3655*5697Smcpowers 
3656*5697Smcpowers     DIGIT(c, used) = (mp_digit)w;
3657*5697Smcpowers     ++used;
3658*5697Smcpowers   }
3659*5697Smcpowers #else
3660*5697Smcpowers   if (carry) {
3661*5697Smcpowers     if((res = s_mp_pad(c, used + 1)) != MP_OKAY)
3662*5697Smcpowers       return res;
3663*5697Smcpowers 
3664*5697Smcpowers     DIGIT(c, used) = carry;
3665*5697Smcpowers     ++used;
3666*5697Smcpowers   }
3667*5697Smcpowers #endif
3668*5697Smcpowers   MP_USED(c) = used;
3669*5697Smcpowers   return MP_OKAY;
3670*5697Smcpowers }
3671*5697Smcpowers /* {{{ s_mp_add_offset(a, b, offset) */
3672*5697Smcpowers 
3673*5697Smcpowers /* Compute a = |a| + ( |b| * (RADIX ** offset) )             */
3674*5697Smcpowers mp_err   s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset)
3675*5697Smcpowers {
3676*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3677*5697Smcpowers   mp_word   w, k = 0;
3678*5697Smcpowers #else
3679*5697Smcpowers   mp_digit  d, sum, carry = 0;
3680*5697Smcpowers #endif
3681*5697Smcpowers   mp_size   ib;
3682*5697Smcpowers   mp_size   ia;
3683*5697Smcpowers   mp_size   lim;
3684*5697Smcpowers   mp_err    res;
3685*5697Smcpowers 
3686*5697Smcpowers   /* Make sure a has enough precision for the output value */
3687*5697Smcpowers   lim = MP_USED(b) + offset;
3688*5697Smcpowers   if((lim > USED(a)) && (res = s_mp_pad(a, lim)) != MP_OKAY)
3689*5697Smcpowers     return res;
3690*5697Smcpowers 
3691*5697Smcpowers   /*
3692*5697Smcpowers     Add up all digits up to the precision of b.  If b had initially
3693*5697Smcpowers     the same precision as a, or greater, we took care of it by the
3694*5697Smcpowers     padding step above, so there is no problem.  If b had initially
3695*5697Smcpowers     less precision, we'll have to make sure the carry out is duly
3696*5697Smcpowers     propagated upward among the higher-order digits of the sum.
3697*5697Smcpowers    */
3698*5697Smcpowers   lim = USED(b);
3699*5697Smcpowers   for(ib = 0, ia = offset; ib < lim; ib++, ia++) {
3700*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3701*5697Smcpowers     w = (mp_word)DIGIT(a, ia) + DIGIT(b, ib) + k;
3702*5697Smcpowers     DIGIT(a, ia) = ACCUM(w);
3703*5697Smcpowers     k = CARRYOUT(w);
3704*5697Smcpowers #else
3705*5697Smcpowers     d = MP_DIGIT(a, ia);
3706*5697Smcpowers     sum = d + MP_DIGIT(b, ib);
3707*5697Smcpowers     d = (sum < d);
3708*5697Smcpowers     MP_DIGIT(a,ia) = sum += carry;
3709*5697Smcpowers     carry = d + (sum < carry);
3710*5697Smcpowers #endif
3711*5697Smcpowers   }
3712*5697Smcpowers 
3713*5697Smcpowers   /* If we run out of 'b' digits before we're actually done, make
3714*5697Smcpowers      sure the carries get propagated upward...
3715*5697Smcpowers    */
3716*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3717*5697Smcpowers   for (lim = MP_USED(a); k && (ia < lim); ++ia) {
3718*5697Smcpowers     w = (mp_word)DIGIT(a, ia) + k;
3719*5697Smcpowers     DIGIT(a, ia) = ACCUM(w);
3720*5697Smcpowers     k = CARRYOUT(w);
3721*5697Smcpowers   }
3722*5697Smcpowers #else
3723*5697Smcpowers   for (lim = MP_USED(a); carry && (ia < lim); ++ia) {
3724*5697Smcpowers     d = MP_DIGIT(a, ia);
3725*5697Smcpowers     MP_DIGIT(a,ia) = sum = d + carry;
3726*5697Smcpowers     carry = (sum < d);
3727*5697Smcpowers   }
3728*5697Smcpowers #endif
3729*5697Smcpowers 
3730*5697Smcpowers   /* If there's an overall carry out, increase precision and include
3731*5697Smcpowers      it.  We could have done this initially, but why touch the memory
3732*5697Smcpowers      allocator unless we're sure we have to?
3733*5697Smcpowers    */
3734*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)
3735*5697Smcpowers   if(k) {
3736*5697Smcpowers     if((res = s_mp_pad(a, USED(a) + 1)) != MP_OKAY)
3737*5697Smcpowers       return res;
3738*5697Smcpowers 
3739*5697Smcpowers     DIGIT(a, ia) = (mp_digit)k;
3740*5697Smcpowers   }
3741*5697Smcpowers #else
3742*5697Smcpowers   if (carry) {
3743*5697Smcpowers     if((res = s_mp_pad(a, lim + 1)) != MP_OKAY)
3744*5697Smcpowers       return res;
3745*5697Smcpowers 
3746*5697Smcpowers     DIGIT(a, lim) = carry;
3747*5697Smcpowers   }
3748*5697Smcpowers #endif
3749*5697Smcpowers   s_mp_clamp(a);
3750*5697Smcpowers 
3751*5697Smcpowers   return MP_OKAY;
3752*5697Smcpowers 
3753*5697Smcpowers } /* end s_mp_add_offset() */
3754*5697Smcpowers 
3755*5697Smcpowers /* }}} */
3756*5697Smcpowers 
3757*5697Smcpowers /* {{{ s_mp_sub(a, b) */
3758*5697Smcpowers 
3759*5697Smcpowers /* Compute a = |a| - |b|, assumes |a| >= |b|                              */
3760*5697Smcpowers mp_err   s_mp_sub(mp_int *a, const mp_int *b)  /* magnitude subtract      */
3761*5697Smcpowers {
3762*5697Smcpowers   mp_digit *pa, *pb, *limit;
3763*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
3764*5697Smcpowers   mp_sword  w = 0;
3765*5697Smcpowers #else
3766*5697Smcpowers   mp_digit  d, diff, borrow = 0;
3767*5697Smcpowers #endif
3768*5697Smcpowers 
3769*5697Smcpowers   /*
3770*5697Smcpowers     Subtract and propagate borrow.  Up to the precision of b, this
3771*5697Smcpowers     accounts for the digits of b; after that, we just make sure the
3772*5697Smcpowers     carries get to the right place.  This saves having to pad b out to
3773*5697Smcpowers     the precision of a just to make the loops work right...
3774*5697Smcpowers    */
3775*5697Smcpowers   pa = MP_DIGITS(a);
3776*5697Smcpowers   pb = MP_DIGITS(b);
3777*5697Smcpowers   limit = pb + MP_USED(b);
3778*5697Smcpowers   while (pb < limit) {
3779*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
3780*5697Smcpowers     w = w + *pa - *pb++;
3781*5697Smcpowers     *pa++ = ACCUM(w);
3782*5697Smcpowers     w >>= MP_DIGIT_BIT;
3783*5697Smcpowers #else
3784*5697Smcpowers     d = *pa;
3785*5697Smcpowers     diff = d - *pb++;
3786*5697Smcpowers     d = (diff > d);				/* detect borrow */
3787*5697Smcpowers     if (borrow && --diff == MP_DIGIT_MAX)
3788*5697Smcpowers       ++d;
3789*5697Smcpowers     *pa++ = diff;
3790*5697Smcpowers     borrow = d;
3791*5697Smcpowers #endif
3792*5697Smcpowers   }
3793*5697Smcpowers   limit = MP_DIGITS(a) + MP_USED(a);
3794*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
3795*5697Smcpowers   while (w && pa < limit) {
3796*5697Smcpowers     w = w + *pa;
3797*5697Smcpowers     *pa++ = ACCUM(w);
3798*5697Smcpowers     w >>= MP_DIGIT_BIT;
3799*5697Smcpowers   }
3800*5697Smcpowers #else
3801*5697Smcpowers   while (borrow && pa < limit) {
3802*5697Smcpowers     d = *pa;
3803*5697Smcpowers     *pa++ = diff = d - borrow;
3804*5697Smcpowers     borrow = (diff > d);
3805*5697Smcpowers   }
3806*5697Smcpowers #endif
3807*5697Smcpowers 
3808*5697Smcpowers   /* Clobber any leading zeroes we created    */
3809*5697Smcpowers   s_mp_clamp(a);
3810*5697Smcpowers 
3811*5697Smcpowers   /*
3812*5697Smcpowers      If there was a borrow out, then |b| > |a| in violation
3813*5697Smcpowers      of our input invariant.  We've already done the work,
3814*5697Smcpowers      but we'll at least complain about it...
3815*5697Smcpowers    */
3816*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
3817*5697Smcpowers   return w ? MP_RANGE : MP_OKAY;
3818*5697Smcpowers #else
3819*5697Smcpowers   return borrow ? MP_RANGE : MP_OKAY;
3820*5697Smcpowers #endif
3821*5697Smcpowers } /* end s_mp_sub() */
3822*5697Smcpowers 
3823*5697Smcpowers /* }}} */
3824*5697Smcpowers 
3825*5697Smcpowers /* Compute c = |a| - |b|, assumes |a| >= |b| */ /* magnitude subtract      */
3826*5697Smcpowers mp_err   s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c)
3827*5697Smcpowers {
3828*5697Smcpowers   mp_digit *pa, *pb, *pc;
3829*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
3830*5697Smcpowers   mp_sword  w = 0;
3831*5697Smcpowers #else
3832*5697Smcpowers   mp_digit  d, diff, borrow = 0;
3833*5697Smcpowers #endif
3834*5697Smcpowers   int       ix, limit;
3835*5697Smcpowers   mp_err    res;
3836*5697Smcpowers 
3837*5697Smcpowers   MP_SIGN(c) = MP_SIGN(a);
3838*5697Smcpowers 
3839*5697Smcpowers   /* Make sure a has enough precision for the output value */
3840*5697Smcpowers   if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))
3841*5697Smcpowers     return res;
3842*5697Smcpowers 
3843*5697Smcpowers   /*
3844*5697Smcpowers     Subtract and propagate borrow.  Up to the precision of b, this
3845*5697Smcpowers     accounts for the digits of b; after that, we just make sure the
3846*5697Smcpowers     carries get to the right place.  This saves having to pad b out to
3847*5697Smcpowers     the precision of a just to make the loops work right...
3848*5697Smcpowers    */
3849*5697Smcpowers   pa = MP_DIGITS(a);
3850*5697Smcpowers   pb = MP_DIGITS(b);
3851*5697Smcpowers   pc = MP_DIGITS(c);
3852*5697Smcpowers   limit = MP_USED(b);
3853*5697Smcpowers   for (ix = 0; ix < limit; ++ix) {
3854*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
3855*5697Smcpowers     w = w + *pa++ - *pb++;
3856*5697Smcpowers     *pc++ = ACCUM(w);
3857*5697Smcpowers     w >>= MP_DIGIT_BIT;
3858*5697Smcpowers #else
3859*5697Smcpowers     d = *pa++;
3860*5697Smcpowers     diff = d - *pb++;
3861*5697Smcpowers     d = (diff > d);
3862*5697Smcpowers     if (borrow && --diff == MP_DIGIT_MAX)
3863*5697Smcpowers       ++d;
3864*5697Smcpowers     *pc++ = diff;
3865*5697Smcpowers     borrow = d;
3866*5697Smcpowers #endif
3867*5697Smcpowers   }
3868*5697Smcpowers   for (limit = MP_USED(a); ix < limit; ++ix) {
3869*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
3870*5697Smcpowers     w = w + *pa++;
3871*5697Smcpowers     *pc++ = ACCUM(w);
3872*5697Smcpowers     w >>= MP_DIGIT_BIT;
3873*5697Smcpowers #else
3874*5697Smcpowers     d = *pa++;
3875*5697Smcpowers     *pc++ = diff = d - borrow;
3876*5697Smcpowers     borrow = (diff > d);
3877*5697Smcpowers #endif
3878*5697Smcpowers   }
3879*5697Smcpowers 
3880*5697Smcpowers   /* Clobber any leading zeroes we created    */
3881*5697Smcpowers   MP_USED(c) = ix;
3882*5697Smcpowers   s_mp_clamp(c);
3883*5697Smcpowers 
3884*5697Smcpowers   /*
3885*5697Smcpowers      If there was a borrow out, then |b| > |a| in violation
3886*5697Smcpowers      of our input invariant.  We've already done the work,
3887*5697Smcpowers      but we'll at least complain about it...
3888*5697Smcpowers    */
3889*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)
3890*5697Smcpowers   return w ? MP_RANGE : MP_OKAY;
3891*5697Smcpowers #else
3892*5697Smcpowers   return borrow ? MP_RANGE : MP_OKAY;
3893*5697Smcpowers #endif
3894*5697Smcpowers }
3895*5697Smcpowers /* {{{ s_mp_mul(a, b) */
3896*5697Smcpowers 
3897*5697Smcpowers /* Compute a = |a| * |b|                                                  */
3898*5697Smcpowers mp_err   s_mp_mul(mp_int *a, const mp_int *b)
3899*5697Smcpowers {
3900*5697Smcpowers   return mp_mul(a, b, a);
3901*5697Smcpowers } /* end s_mp_mul() */
3902*5697Smcpowers 
3903*5697Smcpowers /* }}} */
3904*5697Smcpowers 
3905*5697Smcpowers #if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
3906*5697Smcpowers /* This trick works on Sparc V8 CPUs with the Workshop compilers. */
3907*5697Smcpowers #define MP_MUL_DxD(a, b, Phi, Plo) \
3908*5697Smcpowers   { unsigned long long product = (unsigned long long)a * b; \
3909*5697Smcpowers     Plo = (mp_digit)product; \
3910*5697Smcpowers     Phi = (mp_digit)(product >> MP_DIGIT_BIT); }
3911*5697Smcpowers #elif defined(OSF1)
3912*5697Smcpowers #define MP_MUL_DxD(a, b, Phi, Plo) \
3913*5697Smcpowers   { Plo = asm ("mulq %a0, %a1, %v0", a, b);\
3914*5697Smcpowers     Phi = asm ("umulh %a0, %a1, %v0", a, b); }
3915*5697Smcpowers #else
3916*5697Smcpowers #define MP_MUL_DxD(a, b, Phi, Plo) \
3917*5697Smcpowers   { mp_digit a0b1, a1b0; \
3918*5697Smcpowers     Plo = (a & MP_HALF_DIGIT_MAX) * (b & MP_HALF_DIGIT_MAX); \
3919*5697Smcpowers     Phi = (a >> MP_HALF_DIGIT_BIT) * (b >> MP_HALF_DIGIT_BIT); \
3920*5697Smcpowers     a0b1 = (a & MP_HALF_DIGIT_MAX) * (b >> MP_HALF_DIGIT_BIT); \
3921*5697Smcpowers     a1b0 = (a >> MP_HALF_DIGIT_BIT) * (b & MP_HALF_DIGIT_MAX); \
3922*5697Smcpowers     a1b0 += a0b1; \
3923*5697Smcpowers     Phi += a1b0 >> MP_HALF_DIGIT_BIT; \
3924*5697Smcpowers     if (a1b0 < a0b1)  \
3925*5697Smcpowers       Phi += MP_HALF_RADIX; \
3926*5697Smcpowers     a1b0 <<= MP_HALF_DIGIT_BIT; \
3927*5697Smcpowers     Plo += a1b0; \
3928*5697Smcpowers     if (Plo < a1b0) \
3929*5697Smcpowers       ++Phi; \
3930*5697Smcpowers   }
3931*5697Smcpowers #endif
3932*5697Smcpowers 
3933*5697Smcpowers #if !defined(MP_ASSEMBLY_MULTIPLY)
3934*5697Smcpowers /* c = a * b */
3935*5697Smcpowers void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
3936*5697Smcpowers {
3937*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
3938*5697Smcpowers   mp_digit   d = 0;
3939*5697Smcpowers 
3940*5697Smcpowers   /* Inner product:  Digits of a */
3941*5697Smcpowers   while (a_len--) {
3942*5697Smcpowers     mp_word w = ((mp_word)b * *a++) + d;
3943*5697Smcpowers     *c++ = ACCUM(w);
3944*5697Smcpowers     d = CARRYOUT(w);
3945*5697Smcpowers   }
3946*5697Smcpowers   *c = d;
3947*5697Smcpowers #else
3948*5697Smcpowers   mp_digit carry = 0;
3949*5697Smcpowers   while (a_len--) {
3950*5697Smcpowers     mp_digit a_i = *a++;
3951*5697Smcpowers     mp_digit a0b0, a1b1;
3952*5697Smcpowers 
3953*5697Smcpowers     MP_MUL_DxD(a_i, b, a1b1, a0b0);
3954*5697Smcpowers 
3955*5697Smcpowers     a0b0 += carry;
3956*5697Smcpowers     if (a0b0 < carry)
3957*5697Smcpowers       ++a1b1;
3958*5697Smcpowers     *c++ = a0b0;
3959*5697Smcpowers     carry = a1b1;
3960*5697Smcpowers   }
3961*5697Smcpowers   *c = carry;
3962*5697Smcpowers #endif
3963*5697Smcpowers }
3964*5697Smcpowers 
3965*5697Smcpowers /* c += a * b */
3966*5697Smcpowers void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b,
3967*5697Smcpowers 			      mp_digit *c)
3968*5697Smcpowers {
3969*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
3970*5697Smcpowers   mp_digit   d = 0;
3971*5697Smcpowers 
3972*5697Smcpowers   /* Inner product:  Digits of a */
3973*5697Smcpowers   while (a_len--) {
3974*5697Smcpowers     mp_word w = ((mp_word)b * *a++) + *c + d;
3975*5697Smcpowers     *c++ = ACCUM(w);
3976*5697Smcpowers     d = CARRYOUT(w);
3977*5697Smcpowers   }
3978*5697Smcpowers   *c = d;
3979*5697Smcpowers #else
3980*5697Smcpowers   mp_digit carry = 0;
3981*5697Smcpowers   while (a_len--) {
3982*5697Smcpowers     mp_digit a_i = *a++;
3983*5697Smcpowers     mp_digit a0b0, a1b1;
3984*5697Smcpowers 
3985*5697Smcpowers     MP_MUL_DxD(a_i, b, a1b1, a0b0);
3986*5697Smcpowers 
3987*5697Smcpowers     a0b0 += carry;
3988*5697Smcpowers     if (a0b0 < carry)
3989*5697Smcpowers       ++a1b1;
3990*5697Smcpowers     a0b0 += a_i = *c;
3991*5697Smcpowers     if (a0b0 < a_i)
3992*5697Smcpowers       ++a1b1;
3993*5697Smcpowers     *c++ = a0b0;
3994*5697Smcpowers     carry = a1b1;
3995*5697Smcpowers   }
3996*5697Smcpowers   *c = carry;
3997*5697Smcpowers #endif
3998*5697Smcpowers }
3999*5697Smcpowers 
4000*5697Smcpowers /* Presently, this is only used by the Montgomery arithmetic code. */
4001*5697Smcpowers /* c += a * b */
4002*5697Smcpowers void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
4003*5697Smcpowers {
4004*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
4005*5697Smcpowers   mp_digit   d = 0;
4006*5697Smcpowers 
4007*5697Smcpowers   /* Inner product:  Digits of a */
4008*5697Smcpowers   while (a_len--) {
4009*5697Smcpowers     mp_word w = ((mp_word)b * *a++) + *c + d;
4010*5697Smcpowers     *c++ = ACCUM(w);
4011*5697Smcpowers     d = CARRYOUT(w);
4012*5697Smcpowers   }
4013*5697Smcpowers 
4014*5697Smcpowers   while (d) {
4015*5697Smcpowers     mp_word w = (mp_word)*c + d;
4016*5697Smcpowers     *c++ = ACCUM(w);
4017*5697Smcpowers     d = CARRYOUT(w);
4018*5697Smcpowers   }
4019*5697Smcpowers #else
4020*5697Smcpowers   mp_digit carry = 0;
4021*5697Smcpowers   while (a_len--) {
4022*5697Smcpowers     mp_digit a_i = *a++;
4023*5697Smcpowers     mp_digit a0b0, a1b1;
4024*5697Smcpowers 
4025*5697Smcpowers     MP_MUL_DxD(a_i, b, a1b1, a0b0);
4026*5697Smcpowers 
4027*5697Smcpowers     a0b0 += carry;
4028*5697Smcpowers     if (a0b0 < carry)
4029*5697Smcpowers       ++a1b1;
4030*5697Smcpowers 
4031*5697Smcpowers     a0b0 += a_i = *c;
4032*5697Smcpowers     if (a0b0 < a_i)
4033*5697Smcpowers       ++a1b1;
4034*5697Smcpowers 
4035*5697Smcpowers     *c++ = a0b0;
4036*5697Smcpowers     carry = a1b1;
4037*5697Smcpowers   }
4038*5697Smcpowers   while (carry) {
4039*5697Smcpowers     mp_digit c_i = *c;
4040*5697Smcpowers     carry += c_i;
4041*5697Smcpowers     *c++ = carry;
4042*5697Smcpowers     carry = carry < c_i;
4043*5697Smcpowers   }
4044*5697Smcpowers #endif
4045*5697Smcpowers }
4046*5697Smcpowers #endif
4047*5697Smcpowers 
4048*5697Smcpowers #if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)
4049*5697Smcpowers /* This trick works on Sparc V8 CPUs with the Workshop compilers. */
4050*5697Smcpowers #define MP_SQR_D(a, Phi, Plo) \
4051*5697Smcpowers   { unsigned long long square = (unsigned long long)a * a; \
4052*5697Smcpowers     Plo = (mp_digit)square; \
4053*5697Smcpowers     Phi = (mp_digit)(square >> MP_DIGIT_BIT); }
4054*5697Smcpowers #elif defined(OSF1)
4055*5697Smcpowers #define MP_SQR_D(a, Phi, Plo) \
4056*5697Smcpowers   { Plo = asm ("mulq  %a0, %a0, %v0", a);\
4057*5697Smcpowers     Phi = asm ("umulh %a0, %a0, %v0", a); }
4058*5697Smcpowers #else
4059*5697Smcpowers #define MP_SQR_D(a, Phi, Plo) \
4060*5697Smcpowers   { mp_digit Pmid; \
4061*5697Smcpowers     Plo  = (a  & MP_HALF_DIGIT_MAX) * (a  & MP_HALF_DIGIT_MAX); \
4062*5697Smcpowers     Phi  = (a >> MP_HALF_DIGIT_BIT) * (a >> MP_HALF_DIGIT_BIT); \
4063*5697Smcpowers     Pmid = (a  & MP_HALF_DIGIT_MAX) * (a >> MP_HALF_DIGIT_BIT); \
4064*5697Smcpowers     Phi += Pmid >> (MP_HALF_DIGIT_BIT - 1);  \
4065*5697Smcpowers     Pmid <<= (MP_HALF_DIGIT_BIT + 1);  \
4066*5697Smcpowers     Plo += Pmid;  \
4067*5697Smcpowers     if (Plo < Pmid)  \
4068*5697Smcpowers       ++Phi;  \
4069*5697Smcpowers   }
4070*5697Smcpowers #endif
4071*5697Smcpowers 
4072*5697Smcpowers #if !defined(MP_ASSEMBLY_SQUARE)
4073*5697Smcpowers /* Add the squares of the digits of a to the digits of b. */
4074*5697Smcpowers void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
4075*5697Smcpowers {
4076*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)
4077*5697Smcpowers   mp_word  w;
4078*5697Smcpowers   mp_digit d;
4079*5697Smcpowers   mp_size  ix;
4080*5697Smcpowers 
4081*5697Smcpowers   w  = 0;
4082*5697Smcpowers #define ADD_SQUARE(n) \
4083*5697Smcpowers     d = pa[n]; \
4084*5697Smcpowers     w += (d * (mp_word)d) + ps[2*n]; \
4085*5697Smcpowers     ps[2*n] = ACCUM(w); \
4086*5697Smcpowers     w = (w >> DIGIT_BIT) + ps[2*n+1]; \
4087*5697Smcpowers     ps[2*n+1] = ACCUM(w); \
4088*5697Smcpowers     w = (w >> DIGIT_BIT)
4089*5697Smcpowers 
4090*5697Smcpowers   for (ix = a_len; ix >= 4; ix -= 4) {
4091*5697Smcpowers     ADD_SQUARE(0);
4092*5697Smcpowers     ADD_SQUARE(1);
4093*5697Smcpowers     ADD_SQUARE(2);
4094*5697Smcpowers     ADD_SQUARE(3);
4095*5697Smcpowers     pa += 4;
4096*5697Smcpowers     ps += 8;
4097*5697Smcpowers   }
4098*5697Smcpowers   if (ix) {
4099*5697Smcpowers     ps += 2*ix;
4100*5697Smcpowers     pa += ix;
4101*5697Smcpowers     switch (ix) {
4102*5697Smcpowers     case 3: ADD_SQUARE(-3); /* FALLTHRU */
4103*5697Smcpowers     case 2: ADD_SQUARE(-2); /* FALLTHRU */
4104*5697Smcpowers     case 1: ADD_SQUARE(-1); /* FALLTHRU */
4105*5697Smcpowers     case 0: break;
4106*5697Smcpowers     }
4107*5697Smcpowers   }
4108*5697Smcpowers   while (w) {
4109*5697Smcpowers     w += *ps;
4110*5697Smcpowers     *ps++ = ACCUM(w);
4111*5697Smcpowers     w = (w >> DIGIT_BIT);
4112*5697Smcpowers   }
4113*5697Smcpowers #else
4114*5697Smcpowers   mp_digit carry = 0;
4115*5697Smcpowers   while (a_len--) {
4116*5697Smcpowers     mp_digit a_i = *pa++;
4117*5697Smcpowers     mp_digit a0a0, a1a1;
4118*5697Smcpowers 
4119*5697Smcpowers     MP_SQR_D(a_i, a1a1, a0a0);
4120*5697Smcpowers 
4121*5697Smcpowers     /* here a1a1 and a0a0 constitute a_i ** 2 */
4122*5697Smcpowers     a0a0 += carry;
4123*5697Smcpowers     if (a0a0 < carry)
4124*5697Smcpowers       ++a1a1;
4125*5697Smcpowers 
4126*5697Smcpowers     /* now add to ps */
4127*5697Smcpowers     a0a0 += a_i = *ps;
4128*5697Smcpowers     if (a0a0 < a_i)
4129*5697Smcpowers       ++a1a1;
4130*5697Smcpowers     *ps++ = a0a0;
4131*5697Smcpowers     a1a1 += a_i = *ps;
4132*5697Smcpowers     carry = (a1a1 < a_i);
4133*5697Smcpowers     *ps++ = a1a1;
4134*5697Smcpowers   }
4135*5697Smcpowers   while (carry) {
4136*5697Smcpowers     mp_digit s_i = *ps;
4137*5697Smcpowers     carry += s_i;
4138*5697Smcpowers     *ps++ = carry;
4139*5697Smcpowers     carry = carry < s_i;
4140*5697Smcpowers   }
4141*5697Smcpowers #endif
4142*5697Smcpowers }
4143*5697Smcpowers #endif
4144*5697Smcpowers 
4145*5697Smcpowers #if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) \
4146*5697Smcpowers && !defined(MP_ASSEMBLY_DIV_2DX1D)
4147*5697Smcpowers /*
4148*5697Smcpowers ** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized
4149*5697Smcpowers ** so its high bit is 1.   This code is from NSPR.
4150*5697Smcpowers */
4151*5697Smcpowers mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,
4152*5697Smcpowers 		       mp_digit *qp, mp_digit *rp)
4153*5697Smcpowers {
4154*5697Smcpowers     mp_digit d1, d0, q1, q0;
4155*5697Smcpowers     mp_digit r1, r0, m;
4156*5697Smcpowers 
4157*5697Smcpowers     d1 = divisor >> MP_HALF_DIGIT_BIT;
4158*5697Smcpowers     d0 = divisor & MP_HALF_DIGIT_MAX;
4159*5697Smcpowers     r1 = Nhi % d1;
4160*5697Smcpowers     q1 = Nhi / d1;
4161*5697Smcpowers     m = q1 * d0;
4162*5697Smcpowers     r1 = (r1 << MP_HALF_DIGIT_BIT) | (Nlo >> MP_HALF_DIGIT_BIT);
4163*5697Smcpowers     if (r1 < m) {
4164*5697Smcpowers         q1--, r1 += divisor;
4165*5697Smcpowers         if (r1 >= divisor && r1 < m) {
4166*5697Smcpowers 	    q1--, r1 += divisor;
4167*5697Smcpowers 	}
4168*5697Smcpowers     }
4169*5697Smcpowers     r1 -= m;
4170*5697Smcpowers     r0 = r1 % d1;
4171*5697Smcpowers     q0 = r1 / d1;
4172*5697Smcpowers     m = q0 * d0;
4173*5697Smcpowers     r0 = (r0 << MP_HALF_DIGIT_BIT) | (Nlo & MP_HALF_DIGIT_MAX);
4174*5697Smcpowers     if (r0 < m) {
4175*5697Smcpowers         q0--, r0 += divisor;
4176*5697Smcpowers         if (r0 >= divisor && r0 < m) {
4177*5697Smcpowers 	    q0--, r0 += divisor;
4178*5697Smcpowers 	}
4179*5697Smcpowers     }
4180*5697Smcpowers     if (qp)
4181*5697Smcpowers 	*qp = (q1 << MP_HALF_DIGIT_BIT) | q0;
4182*5697Smcpowers     if (rp)
4183*5697Smcpowers 	*rp = r0 - m;
4184*5697Smcpowers     return MP_OKAY;
4185*5697Smcpowers }
4186*5697Smcpowers #endif
4187*5697Smcpowers 
4188*5697Smcpowers #if MP_SQUARE
4189*5697Smcpowers /* {{{ s_mp_sqr(a) */
4190*5697Smcpowers 
4191*5697Smcpowers mp_err   s_mp_sqr(mp_int *a)
4192*5697Smcpowers {
4193*5697Smcpowers   mp_err   res;
4194*5697Smcpowers   mp_int   tmp;
4195*5697Smcpowers 
4196*5697Smcpowers   if((res = mp_init_size(&tmp, 2 * USED(a), FLAG(a))) != MP_OKAY)
4197*5697Smcpowers     return res;
4198*5697Smcpowers   res = mp_sqr(a, &tmp);
4199*5697Smcpowers   if (res == MP_OKAY) {
4200*5697Smcpowers     s_mp_exch(&tmp, a);
4201*5697Smcpowers   }
4202*5697Smcpowers   mp_clear(&tmp);
4203*5697Smcpowers   return res;
4204*5697Smcpowers }
4205*5697Smcpowers 
4206*5697Smcpowers /* }}} */
4207*5697Smcpowers #endif
4208*5697Smcpowers 
4209*5697Smcpowers /* {{{ s_mp_div(a, b) */
4210*5697Smcpowers 
4211*5697Smcpowers /*
4212*5697Smcpowers   s_mp_div(a, b)
4213*5697Smcpowers 
4214*5697Smcpowers   Compute a = a / b and b = a mod b.  Assumes b > a.
4215*5697Smcpowers  */
4216*5697Smcpowers 
4217*5697Smcpowers mp_err   s_mp_div(mp_int *rem, 	/* i: dividend, o: remainder */
4218*5697Smcpowers                   mp_int *div, 	/* i: divisor                */
4219*5697Smcpowers 		  mp_int *quot)	/* i: 0;        o: quotient  */
4220*5697Smcpowers {
4221*5697Smcpowers   mp_int   part, t;
4222*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
4223*5697Smcpowers   mp_word  q_msd;
4224*5697Smcpowers #else
4225*5697Smcpowers   mp_digit q_msd;
4226*5697Smcpowers #endif
4227*5697Smcpowers   mp_err   res;
4228*5697Smcpowers   mp_digit d;
4229*5697Smcpowers   mp_digit div_msd;
4230*5697Smcpowers   int      ix;
4231*5697Smcpowers 
4232*5697Smcpowers   if(mp_cmp_z(div) == 0)
4233*5697Smcpowers     return MP_RANGE;
4234*5697Smcpowers 
4235*5697Smcpowers   /* Shortcut if divisor is power of two */
4236*5697Smcpowers   if((ix = s_mp_ispow2(div)) >= 0) {
4237*5697Smcpowers     MP_CHECKOK( mp_copy(rem, quot) );
4238*5697Smcpowers     s_mp_div_2d(quot, (mp_digit)ix);
4239*5697Smcpowers     s_mp_mod_2d(rem,  (mp_digit)ix);
4240*5697Smcpowers 
4241*5697Smcpowers     return MP_OKAY;
4242*5697Smcpowers   }
4243*5697Smcpowers 
4244*5697Smcpowers   DIGITS(&t) = 0;
4245*5697Smcpowers   MP_SIGN(rem) = ZPOS;
4246*5697Smcpowers   MP_SIGN(div) = ZPOS;
4247*5697Smcpowers 
4248*5697Smcpowers   /* A working temporary for division     */
4249*5697Smcpowers   MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem), FLAG(rem)));
4250*5697Smcpowers 
4251*5697Smcpowers   /* Normalize to optimize guessing       */
4252*5697Smcpowers   MP_CHECKOK( s_mp_norm(rem, div, &d) );
4253*5697Smcpowers 
4254*5697Smcpowers   part = *rem;
4255*5697Smcpowers 
4256*5697Smcpowers   /* Perform the division itself...woo!   */
4257*5697Smcpowers   MP_USED(quot) = MP_ALLOC(quot);
4258*5697Smcpowers 
4259*5697Smcpowers   /* Find a partial substring of rem which is at least div */
4260*5697Smcpowers   /* If we didn't find one, we're finished dividing    */
4261*5697Smcpowers   while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) {
4262*5697Smcpowers     int i;
4263*5697Smcpowers     int unusedRem;
4264*5697Smcpowers 
4265*5697Smcpowers     unusedRem = MP_USED(rem) - MP_USED(div);
4266*5697Smcpowers     MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem;
4267*5697Smcpowers     MP_ALLOC(&part)  = MP_ALLOC(rem)  - unusedRem;
4268*5697Smcpowers     MP_USED(&part)   = MP_USED(div);
4269*5697Smcpowers     if (s_mp_cmp(&part, div) < 0) {
4270*5697Smcpowers       -- unusedRem;
4271*5697Smcpowers #if MP_ARGCHK == 2
4272*5697Smcpowers       assert(unusedRem >= 0);
4273*5697Smcpowers #endif
4274*5697Smcpowers       -- MP_DIGITS(&part);
4275*5697Smcpowers       ++ MP_USED(&part);
4276*5697Smcpowers       ++ MP_ALLOC(&part);
4277*5697Smcpowers     }
4278*5697Smcpowers 
4279*5697Smcpowers     /* Compute a guess for the next quotient digit       */
4280*5697Smcpowers     q_msd = MP_DIGIT(&part, MP_USED(&part) - 1);
4281*5697Smcpowers     div_msd = MP_DIGIT(div, MP_USED(div) - 1);
4282*5697Smcpowers     if (q_msd >= div_msd) {
4283*5697Smcpowers       q_msd = 1;
4284*5697Smcpowers     } else if (MP_USED(&part) > 1) {
4285*5697Smcpowers #if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)
4286*5697Smcpowers       q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);
4287*5697Smcpowers       q_msd /= div_msd;
4288*5697Smcpowers       if (q_msd == RADIX)
4289*5697Smcpowers         --q_msd;
4290*5697Smcpowers #else
4291*5697Smcpowers       mp_digit r;
4292*5697Smcpowers       MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),
4293*5697Smcpowers 				  div_msd, &q_msd, &r) );
4294*5697Smcpowers #endif
4295*5697Smcpowers     } else {
4296*5697Smcpowers       q_msd = 0;
4297*5697Smcpowers     }
4298*5697Smcpowers #if MP_ARGCHK == 2
4299*5697Smcpowers     assert(q_msd > 0); /* This case should never occur any more. */
4300*5697Smcpowers #endif
4301*5697Smcpowers     if (q_msd <= 0)
4302*5697Smcpowers       break;
4303*5697Smcpowers 
4304*5697Smcpowers     /* See what that multiplies out to                   */
4305*5697Smcpowers     mp_copy(div, &t);
4306*5697Smcpowers     MP_CHECKOK( s_mp_mul_d(&t, (mp_digit)q_msd) );
4307*5697Smcpowers 
4308*5697Smcpowers     /*
4309*5697Smcpowers        If it's too big, back it off.  We should not have to do this
4310*5697Smcpowers        more than once, or, in rare cases, twice.  Knuth describes a
4311*5697Smcpowers        method by which this could be reduced to a maximum of once, but
4312*5697Smcpowers        I didn't implement that here.
4313*5697Smcpowers      * When using s_mpv_div_2dx1d, we may have to do this 3 times.
4314*5697Smcpowers      */
4315*5697Smcpowers     for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {
4316*5697Smcpowers       --q_msd;
4317*5697Smcpowers       s_mp_sub(&t, div);	/* t -= div */
4318*5697Smcpowers     }
4319*5697Smcpowers     if (i < 0) {
4320*5697Smcpowers       res = MP_RANGE;
4321*5697Smcpowers       goto CLEANUP;
4322*5697Smcpowers     }
4323*5697Smcpowers 
4324*5697Smcpowers     /* At this point, q_msd should be the right next digit   */
4325*5697Smcpowers     MP_CHECKOK( s_mp_sub(&part, &t) );	/* part -= t */
4326*5697Smcpowers     s_mp_clamp(rem);
4327*5697Smcpowers 
4328*5697Smcpowers     /*
4329*5697Smcpowers       Include the digit in the quotient.  We allocated enough memory
4330*5697Smcpowers       for any quotient we could ever possibly get, so we should not
4331*5697Smcpowers       have to check for failures here
4332*5697Smcpowers      */
4333*5697Smcpowers     MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd;
4334*5697Smcpowers   }
4335*5697Smcpowers 
4336*5697Smcpowers   /* Denormalize remainder                */
4337*5697Smcpowers   if (d) {
4338*5697Smcpowers     s_mp_div_2d(rem, d);
4339*5697Smcpowers   }
4340*5697Smcpowers 
4341*5697Smcpowers   s_mp_clamp(quot);
4342*5697Smcpowers 
4343*5697Smcpowers CLEANUP:
4344*5697Smcpowers   mp_clear(&t);
4345*5697Smcpowers 
4346*5697Smcpowers   return res;
4347*5697Smcpowers 
4348*5697Smcpowers } /* end s_mp_div() */
4349*5697Smcpowers 
4350*5697Smcpowers 
4351*5697Smcpowers /* }}} */
4352*5697Smcpowers 
4353*5697Smcpowers /* {{{ s_mp_2expt(a, k) */
4354*5697Smcpowers 
4355*5697Smcpowers mp_err   s_mp_2expt(mp_int *a, mp_digit k)
4356*5697Smcpowers {
4357*5697Smcpowers   mp_err    res;
4358*5697Smcpowers   mp_size   dig, bit;
4359*5697Smcpowers 
4360*5697Smcpowers   dig = k / DIGIT_BIT;
4361*5697Smcpowers   bit = k % DIGIT_BIT;
4362*5697Smcpowers 
4363*5697Smcpowers   mp_zero(a);
4364*5697Smcpowers   if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
4365*5697Smcpowers     return res;
4366*5697Smcpowers 
4367*5697Smcpowers   DIGIT(a, dig) |= ((mp_digit)1 << bit);
4368*5697Smcpowers 
4369*5697Smcpowers   return MP_OKAY;
4370*5697Smcpowers 
4371*5697Smcpowers } /* end s_mp_2expt() */
4372*5697Smcpowers 
4373*5697Smcpowers /* }}} */
4374*5697Smcpowers 
4375*5697Smcpowers /* {{{ s_mp_reduce(x, m, mu) */
4376*5697Smcpowers 
4377*5697Smcpowers /*
4378*5697Smcpowers   Compute Barrett reduction, x (mod m), given a precomputed value for
4379*5697Smcpowers   mu = b^2k / m, where b = RADIX and k = #digits(m).  This should be
4380*5697Smcpowers   faster than straight division, when many reductions by the same
4381*5697Smcpowers   value of m are required (such as in modular exponentiation).  This
4382*5697Smcpowers   can nearly halve the time required to do modular exponentiation,
4383*5697Smcpowers   as compared to using the full integer divide to reduce.
4384*5697Smcpowers 
4385*5697Smcpowers   This algorithm was derived from the _Handbook of Applied
4386*5697Smcpowers   Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14,
4387*5697Smcpowers   pp. 603-604.
4388*5697Smcpowers  */
4389*5697Smcpowers 
4390*5697Smcpowers mp_err   s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)
4391*5697Smcpowers {
4392*5697Smcpowers   mp_int   q;
4393*5697Smcpowers   mp_err   res;
4394*5697Smcpowers 
4395*5697Smcpowers   if((res = mp_init_copy(&q, x)) != MP_OKAY)
4396*5697Smcpowers     return res;
4397*5697Smcpowers 
4398*5697Smcpowers   s_mp_rshd(&q, USED(m) - 1);  /* q1 = x / b^(k-1)  */
4399*5697Smcpowers   s_mp_mul(&q, mu);            /* q2 = q1 * mu      */
4400*5697Smcpowers   s_mp_rshd(&q, USED(m) + 1);  /* q3 = q2 / b^(k+1) */
4401*5697Smcpowers 
4402*5697Smcpowers   /* x = x mod b^(k+1), quick (no division) */
4403*5697Smcpowers   s_mp_mod_2d(x, DIGIT_BIT * (USED(m) + 1));
4404*5697Smcpowers 
4405*5697Smcpowers   /* q = q * m mod b^(k+1), quick (no division) */
4406*5697Smcpowers   s_mp_mul(&q, m);
4407*5697Smcpowers   s_mp_mod_2d(&q, DIGIT_BIT * (USED(m) + 1));
4408*5697Smcpowers 
4409*5697Smcpowers   /* x = x - q */
4410*5697Smcpowers   if((res = mp_sub(x, &q, x)) != MP_OKAY)
4411*5697Smcpowers     goto CLEANUP;
4412*5697Smcpowers 
4413*5697Smcpowers   /* If x < 0, add b^(k+1) to it */
4414*5697Smcpowers   if(mp_cmp_z(x) < 0) {
4415*5697Smcpowers     mp_set(&q, 1);
4416*5697Smcpowers     if((res = s_mp_lshd(&q, USED(m) + 1)) != MP_OKAY)
4417*5697Smcpowers       goto CLEANUP;
4418*5697Smcpowers     if((res = mp_add(x, &q, x)) != MP_OKAY)
4419*5697Smcpowers       goto CLEANUP;
4420*5697Smcpowers   }
4421*5697Smcpowers 
4422*5697Smcpowers   /* Back off if it's too big */
4423*5697Smcpowers   while(mp_cmp(x, m) >= 0) {
4424*5697Smcpowers     if((res = s_mp_sub(x, m)) != MP_OKAY)
4425*5697Smcpowers       break;
4426*5697Smcpowers   }
4427*5697Smcpowers 
4428*5697Smcpowers  CLEANUP:
4429*5697Smcpowers   mp_clear(&q);
4430*5697Smcpowers 
4431*5697Smcpowers   return res;
4432*5697Smcpowers 
4433*5697Smcpowers } /* end s_mp_reduce() */
4434*5697Smcpowers 
4435*5697Smcpowers /* }}} */
4436*5697Smcpowers 
4437*5697Smcpowers /* }}} */
4438*5697Smcpowers 
4439*5697Smcpowers /* {{{ Primitive comparisons */
4440*5697Smcpowers 
4441*5697Smcpowers /* {{{ s_mp_cmp(a, b) */
4442*5697Smcpowers 
4443*5697Smcpowers /* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b           */
4444*5697Smcpowers int      s_mp_cmp(const mp_int *a, const mp_int *b)
4445*5697Smcpowers {
4446*5697Smcpowers   mp_size used_a = MP_USED(a);
4447*5697Smcpowers   {
4448*5697Smcpowers     mp_size used_b = MP_USED(b);
4449*5697Smcpowers 
4450*5697Smcpowers     if (used_a > used_b)
4451*5697Smcpowers       goto IS_GT;
4452*5697Smcpowers     if (used_a < used_b)
4453*5697Smcpowers       goto IS_LT;
4454*5697Smcpowers   }
4455*5697Smcpowers   {
4456*5697Smcpowers     mp_digit *pa, *pb;
4457*5697Smcpowers     mp_digit da = 0, db = 0;
4458*5697Smcpowers 
4459*5697Smcpowers #define CMP_AB(n) if ((da = pa[n]) != (db = pb[n])) goto done
4460*5697Smcpowers 
4461*5697Smcpowers     pa = MP_DIGITS(a) + used_a;
4462*5697Smcpowers     pb = MP_DIGITS(b) + used_a;
4463*5697Smcpowers     while (used_a >= 4) {
4464*5697Smcpowers       pa     -= 4;
4465*5697Smcpowers       pb     -= 4;
4466*5697Smcpowers       used_a -= 4;
4467*5697Smcpowers       CMP_AB(3);
4468*5697Smcpowers       CMP_AB(2);
4469*5697Smcpowers       CMP_AB(1);
4470*5697Smcpowers       CMP_AB(0);
4471*5697Smcpowers     }
4472*5697Smcpowers     while (used_a-- > 0 && ((da = *--pa) == (db = *--pb)))
4473*5697Smcpowers       /* do nothing */;
4474*5697Smcpowers done:
4475*5697Smcpowers     if (da > db)
4476*5697Smcpowers       goto IS_GT;
4477*5697Smcpowers     if (da < db)
4478*5697Smcpowers       goto IS_LT;
4479*5697Smcpowers   }
4480*5697Smcpowers   return MP_EQ;
4481*5697Smcpowers IS_LT:
4482*5697Smcpowers   return MP_LT;
4483*5697Smcpowers IS_GT:
4484*5697Smcpowers   return MP_GT;
4485*5697Smcpowers } /* end s_mp_cmp() */
4486*5697Smcpowers 
4487*5697Smcpowers /* }}} */
4488*5697Smcpowers 
4489*5697Smcpowers /* {{{ s_mp_cmp_d(a, d) */
4490*5697Smcpowers 
4491*5697Smcpowers /* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d             */
4492*5697Smcpowers int      s_mp_cmp_d(const mp_int *a, mp_digit d)
4493*5697Smcpowers {
4494*5697Smcpowers   if(USED(a) > 1)
4495*5697Smcpowers     return MP_GT;
4496*5697Smcpowers 
4497*5697Smcpowers   if(DIGIT(a, 0) < d)
4498*5697Smcpowers     return MP_LT;
4499*5697Smcpowers   else if(DIGIT(a, 0) > d)
4500*5697Smcpowers     return MP_GT;
4501*5697Smcpowers   else
4502*5697Smcpowers     return MP_EQ;
4503*5697Smcpowers 
4504*5697Smcpowers } /* end s_mp_cmp_d() */
4505*5697Smcpowers 
4506*5697Smcpowers /* }}} */
4507*5697Smcpowers 
4508*5697Smcpowers /* {{{ s_mp_ispow2(v) */
4509*5697Smcpowers 
4510*5697Smcpowers /*
4511*5697Smcpowers   Returns -1 if the value is not a power of two; otherwise, it returns
4512*5697Smcpowers   k such that v = 2^k, i.e. lg(v).
4513*5697Smcpowers  */
4514*5697Smcpowers int      s_mp_ispow2(const mp_int *v)
4515*5697Smcpowers {
4516*5697Smcpowers   mp_digit d;
4517*5697Smcpowers   int      extra = 0, ix;
4518*5697Smcpowers 
4519*5697Smcpowers   ix = MP_USED(v) - 1;
4520*5697Smcpowers   d = MP_DIGIT(v, ix); /* most significant digit of v */
4521*5697Smcpowers 
4522*5697Smcpowers   extra = s_mp_ispow2d(d);
4523*5697Smcpowers   if (extra < 0 || ix == 0)
4524*5697Smcpowers     return extra;
4525*5697Smcpowers 
4526*5697Smcpowers   while (--ix >= 0) {
4527*5697Smcpowers     if (DIGIT(v, ix) != 0)
4528*5697Smcpowers       return -1; /* not a power of two */
4529*5697Smcpowers     extra += MP_DIGIT_BIT;
4530*5697Smcpowers   }
4531*5697Smcpowers 
4532*5697Smcpowers   return extra;
4533*5697Smcpowers 
4534*5697Smcpowers } /* end s_mp_ispow2() */
4535*5697Smcpowers 
4536*5697Smcpowers /* }}} */
4537*5697Smcpowers 
4538*5697Smcpowers /* {{{ s_mp_ispow2d(d) */
4539*5697Smcpowers 
4540*5697Smcpowers int      s_mp_ispow2d(mp_digit d)
4541*5697Smcpowers {
4542*5697Smcpowers   if ((d != 0) && ((d & (d-1)) == 0)) { /* d is a power of 2 */
4543*5697Smcpowers     int pow = 0;
4544*5697Smcpowers #if defined (MP_USE_UINT_DIGIT)
4545*5697Smcpowers     if (d & 0xffff0000U)
4546*5697Smcpowers       pow += 16;
4547*5697Smcpowers     if (d & 0xff00ff00U)
4548*5697Smcpowers       pow += 8;
4549*5697Smcpowers     if (d & 0xf0f0f0f0U)
4550*5697Smcpowers       pow += 4;
4551*5697Smcpowers     if (d & 0xccccccccU)
4552*5697Smcpowers       pow += 2;
4553*5697Smcpowers     if (d & 0xaaaaaaaaU)
4554*5697Smcpowers       pow += 1;
4555*5697Smcpowers #elif defined(MP_USE_LONG_LONG_DIGIT)
4556*5697Smcpowers     if (d & 0xffffffff00000000ULL)
4557*5697Smcpowers       pow += 32;
4558*5697Smcpowers     if (d & 0xffff0000ffff0000ULL)
4559*5697Smcpowers       pow += 16;
4560*5697Smcpowers     if (d & 0xff00ff00ff00ff00ULL)
4561*5697Smcpowers       pow += 8;
4562*5697Smcpowers     if (d & 0xf0f0f0f0f0f0f0f0ULL)
4563*5697Smcpowers       pow += 4;
4564*5697Smcpowers     if (d & 0xccccccccccccccccULL)
4565*5697Smcpowers       pow += 2;
4566*5697Smcpowers     if (d & 0xaaaaaaaaaaaaaaaaULL)
4567*5697Smcpowers       pow += 1;
4568*5697Smcpowers #elif defined(MP_USE_LONG_DIGIT)
4569*5697Smcpowers     if (d & 0xffffffff00000000UL)
4570*5697Smcpowers       pow += 32;
4571*5697Smcpowers     if (d & 0xffff0000ffff0000UL)
4572*5697Smcpowers       pow += 16;
4573*5697Smcpowers     if (d & 0xff00ff00ff00ff00UL)
4574*5697Smcpowers       pow += 8;
4575*5697Smcpowers     if (d & 0xf0f0f0f0f0f0f0f0UL)
4576*5697Smcpowers       pow += 4;
4577*5697Smcpowers     if (d & 0xccccccccccccccccUL)
4578*5697Smcpowers       pow += 2;
4579*5697Smcpowers     if (d & 0xaaaaaaaaaaaaaaaaUL)
4580*5697Smcpowers       pow += 1;
4581*5697Smcpowers #else
4582*5697Smcpowers #error "unknown type for mp_digit"
4583*5697Smcpowers #endif
4584*5697Smcpowers     return pow;
4585*5697Smcpowers   }
4586*5697Smcpowers   return -1;
4587*5697Smcpowers 
4588*5697Smcpowers } /* end s_mp_ispow2d() */
4589*5697Smcpowers 
4590*5697Smcpowers /* }}} */
4591*5697Smcpowers 
4592*5697Smcpowers /* }}} */
4593*5697Smcpowers 
4594*5697Smcpowers /* {{{ Primitive I/O helpers */
4595*5697Smcpowers 
4596*5697Smcpowers /* {{{ s_mp_tovalue(ch, r) */
4597*5697Smcpowers 
4598*5697Smcpowers /*
4599*5697Smcpowers   Convert the given character to its digit value, in the given radix.
4600*5697Smcpowers   If the given character is not understood in the given radix, -1 is
4601*5697Smcpowers   returned.  Otherwise the digit's numeric value is returned.
4602*5697Smcpowers 
4603*5697Smcpowers   The results will be odd if you use a radix < 2 or > 62, you are
4604*5697Smcpowers   expected to know what you're up to.
4605*5697Smcpowers  */
4606*5697Smcpowers int      s_mp_tovalue(char ch, int r)
4607*5697Smcpowers {
4608*5697Smcpowers   int    val, xch;
4609*5697Smcpowers 
4610*5697Smcpowers   if(r > 36)
4611*5697Smcpowers     xch = ch;
4612*5697Smcpowers   else
4613*5697Smcpowers     xch = toupper(ch);
4614*5697Smcpowers 
4615*5697Smcpowers   if(isdigit(xch))
4616*5697Smcpowers     val = xch - '0';
4617*5697Smcpowers   else if(isupper(xch))
4618*5697Smcpowers     val = xch - 'A' + 10;
4619*5697Smcpowers   else if(islower(xch))
4620*5697Smcpowers     val = xch - 'a' + 36;
4621*5697Smcpowers   else if(xch == '+')
4622*5697Smcpowers     val = 62;
4623*5697Smcpowers   else if(xch == '/')
4624*5697Smcpowers     val = 63;
4625*5697Smcpowers   else
4626*5697Smcpowers     return -1;
4627*5697Smcpowers 
4628*5697Smcpowers   if(val < 0 || val >= r)
4629*5697Smcpowers     return -1;
4630*5697Smcpowers 
4631*5697Smcpowers   return val;
4632*5697Smcpowers 
4633*5697Smcpowers } /* end s_mp_tovalue() */
4634*5697Smcpowers 
4635*5697Smcpowers /* }}} */
4636*5697Smcpowers 
4637*5697Smcpowers /* {{{ s_mp_todigit(val, r, low) */
4638*5697Smcpowers 
4639*5697Smcpowers /*
4640*5697Smcpowers   Convert val to a radix-r digit, if possible.  If val is out of range
4641*5697Smcpowers   for r, returns zero.  Otherwise, returns an ASCII character denoting
4642*5697Smcpowers   the value in the given radix.
4643*5697Smcpowers 
4644*5697Smcpowers   The results may be odd if you use a radix < 2 or > 64, you are
4645*5697Smcpowers   expected to know what you're doing.
4646*5697Smcpowers  */
4647*5697Smcpowers 
4648*5697Smcpowers char     s_mp_todigit(mp_digit val, int r, int low)
4649*5697Smcpowers {
4650*5697Smcpowers   char   ch;
4651*5697Smcpowers 
4652*5697Smcpowers   if(val >= r)
4653*5697Smcpowers     return 0;
4654*5697Smcpowers 
4655*5697Smcpowers   ch = s_dmap_1[val];
4656*5697Smcpowers 
4657*5697Smcpowers   if(r <= 36 && low)
4658*5697Smcpowers     ch = tolower(ch);
4659*5697Smcpowers 
4660*5697Smcpowers   return ch;
4661*5697Smcpowers 
4662*5697Smcpowers } /* end s_mp_todigit() */
4663*5697Smcpowers 
4664*5697Smcpowers /* }}} */
4665*5697Smcpowers 
4666*5697Smcpowers /* {{{ s_mp_outlen(bits, radix) */
4667*5697Smcpowers 
4668*5697Smcpowers /*
4669*5697Smcpowers    Return an estimate for how long a string is needed to hold a radix
4670*5697Smcpowers    r representation of a number with 'bits' significant bits, plus an
4671*5697Smcpowers    extra for a zero terminator (assuming C style strings here)
4672*5697Smcpowers  */
4673*5697Smcpowers int      s_mp_outlen(int bits, int r)
4674*5697Smcpowers {
4675*5697Smcpowers   return (int)((double)bits * LOG_V_2(r) + 1.5) + 1;
4676*5697Smcpowers 
4677*5697Smcpowers } /* end s_mp_outlen() */
4678*5697Smcpowers 
4679*5697Smcpowers /* }}} */
4680*5697Smcpowers 
4681*5697Smcpowers /* }}} */
4682*5697Smcpowers 
4683*5697Smcpowers /* {{{ mp_read_unsigned_octets(mp, str, len) */
4684*5697Smcpowers /* mp_read_unsigned_octets(mp, str, len)
4685*5697Smcpowers    Read in a raw value (base 256) into the given mp_int
4686*5697Smcpowers    No sign bit, number is positive.  Leading zeros ignored.
4687*5697Smcpowers  */
4688*5697Smcpowers 
4689*5697Smcpowers mp_err
4690*5697Smcpowers mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len)
4691*5697Smcpowers {
4692*5697Smcpowers   int            count;
4693*5697Smcpowers   mp_err         res;
4694*5697Smcpowers   mp_digit       d;
4695*5697Smcpowers 
4696*5697Smcpowers   ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
4697*5697Smcpowers 
4698*5697Smcpowers   mp_zero(mp);
4699*5697Smcpowers 
4700*5697Smcpowers   count = len % sizeof(mp_digit);
4701*5697Smcpowers   if (count) {
4702*5697Smcpowers     for (d = 0; count-- > 0; --len) {
4703*5697Smcpowers       d = (d << 8) | *str++;
4704*5697Smcpowers     }
4705*5697Smcpowers     MP_DIGIT(mp, 0) = d;
4706*5697Smcpowers   }
4707*5697Smcpowers 
4708*5697Smcpowers   /* Read the rest of the digits */
4709*5697Smcpowers   for(; len > 0; len -= sizeof(mp_digit)) {
4710*5697Smcpowers     for (d = 0, count = sizeof(mp_digit); count > 0; --count) {
4711*5697Smcpowers       d = (d << 8) | *str++;
4712*5697Smcpowers     }
4713*5697Smcpowers     if (MP_EQ == mp_cmp_z(mp)) {
4714*5697Smcpowers       if (!d)
4715*5697Smcpowers 	continue;
4716*5697Smcpowers     } else {
4717*5697Smcpowers       if((res = s_mp_lshd(mp, 1)) != MP_OKAY)
4718*5697Smcpowers 	return res;
4719*5697Smcpowers     }
4720*5697Smcpowers     MP_DIGIT(mp, 0) = d;
4721*5697Smcpowers   }
4722*5697Smcpowers   return MP_OKAY;
4723*5697Smcpowers } /* end mp_read_unsigned_octets() */
4724*5697Smcpowers /* }}} */
4725*5697Smcpowers 
4726*5697Smcpowers /* {{{ mp_unsigned_octet_size(mp) */
4727*5697Smcpowers int
4728*5697Smcpowers mp_unsigned_octet_size(const mp_int *mp)
4729*5697Smcpowers {
4730*5697Smcpowers   int  bytes;
4731*5697Smcpowers   int  ix;
4732*5697Smcpowers   mp_digit  d = 0;
4733*5697Smcpowers 
4734*5697Smcpowers   ARGCHK(mp != NULL, MP_BADARG);
4735*5697Smcpowers   ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG);
4736*5697Smcpowers 
4737*5697Smcpowers   bytes = (USED(mp) * sizeof(mp_digit));
4738*5697Smcpowers 
4739*5697Smcpowers   /* subtract leading zeros. */
4740*5697Smcpowers   /* Iterate over each digit... */
4741*5697Smcpowers   for(ix = USED(mp) - 1; ix >= 0; ix--) {
4742*5697Smcpowers     d = DIGIT(mp, ix);
4743*5697Smcpowers     if (d)
4744*5697Smcpowers 	break;
4745*5697Smcpowers     bytes -= sizeof(d);
4746*5697Smcpowers   }
4747*5697Smcpowers   if (!bytes)
4748*5697Smcpowers     return 1;
4749*5697Smcpowers 
4750*5697Smcpowers   /* Have MSD, check digit bytes, high order first */
4751*5697Smcpowers   for(ix = sizeof(mp_digit) - 1; ix >= 0; ix--) {
4752*5697Smcpowers     unsigned char x = (unsigned char)(d >> (ix * CHAR_BIT));
4753*5697Smcpowers     if (x)
4754*5697Smcpowers 	break;
4755*5697Smcpowers     --bytes;
4756*5697Smcpowers   }
4757*5697Smcpowers   return bytes;
4758*5697Smcpowers } /* end mp_unsigned_octet_size() */
4759*5697Smcpowers /* }}} */
4760*5697Smcpowers 
4761*5697Smcpowers /* {{{ mp_to_unsigned_octets(mp, str) */
4762*5697Smcpowers /* output a buffer of big endian octets no longer than specified. */
4763*5697Smcpowers mp_err
4764*5697Smcpowers mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
4765*5697Smcpowers {
4766*5697Smcpowers   int  ix, pos = 0;
4767*5697Smcpowers   int  bytes;
4768*5697Smcpowers 
4769*5697Smcpowers   ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
4770*5697Smcpowers 
4771*5697Smcpowers   bytes = mp_unsigned_octet_size(mp);
4772*5697Smcpowers   ARGCHK(bytes <= maxlen, MP_BADARG);
4773*5697Smcpowers 
4774*5697Smcpowers   /* Iterate over each digit... */
4775*5697Smcpowers   for(ix = USED(mp) - 1; ix >= 0; ix--) {
4776*5697Smcpowers     mp_digit  d = DIGIT(mp, ix);
4777*5697Smcpowers     int       jx;
4778*5697Smcpowers 
4779*5697Smcpowers     /* Unpack digit bytes, high order first */
4780*5697Smcpowers     for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
4781*5697Smcpowers       unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
4782*5697Smcpowers       if (!pos && !x)	/* suppress leading zeros */
4783*5697Smcpowers 	continue;
4784*5697Smcpowers       str[pos++] = x;
4785*5697Smcpowers     }
4786*5697Smcpowers   }
4787*5697Smcpowers   if (!pos)
4788*5697Smcpowers     str[pos++] = 0;
4789*5697Smcpowers   return pos;
4790*5697Smcpowers } /* end mp_to_unsigned_octets() */
4791*5697Smcpowers /* }}} */
4792*5697Smcpowers 
4793*5697Smcpowers /* {{{ mp_to_signed_octets(mp, str) */
4794*5697Smcpowers /* output a buffer of big endian octets no longer than specified. */
4795*5697Smcpowers mp_err
4796*5697Smcpowers mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)
4797*5697Smcpowers {
4798*5697Smcpowers   int  ix, pos = 0;
4799*5697Smcpowers   int  bytes;
4800*5697Smcpowers 
4801*5697Smcpowers   ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
4802*5697Smcpowers 
4803*5697Smcpowers   bytes = mp_unsigned_octet_size(mp);
4804*5697Smcpowers   ARGCHK(bytes <= maxlen, MP_BADARG);
4805*5697Smcpowers 
4806*5697Smcpowers   /* Iterate over each digit... */
4807*5697Smcpowers   for(ix = USED(mp) - 1; ix >= 0; ix--) {
4808*5697Smcpowers     mp_digit  d = DIGIT(mp, ix);
4809*5697Smcpowers     int       jx;
4810*5697Smcpowers 
4811*5697Smcpowers     /* Unpack digit bytes, high order first */
4812*5697Smcpowers     for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
4813*5697Smcpowers       unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
4814*5697Smcpowers       if (!pos) {
4815*5697Smcpowers 	if (!x)		/* suppress leading zeros */
4816*5697Smcpowers 	  continue;
4817*5697Smcpowers 	if (x & 0x80) { /* add one leading zero to make output positive.  */
4818*5697Smcpowers 	  ARGCHK(bytes + 1 <= maxlen, MP_BADARG);
4819*5697Smcpowers 	  if (bytes + 1 > maxlen)
4820*5697Smcpowers 	    return MP_BADARG;
4821*5697Smcpowers 	  str[pos++] = 0;
4822*5697Smcpowers 	}
4823*5697Smcpowers       }
4824*5697Smcpowers       str[pos++] = x;
4825*5697Smcpowers     }
4826*5697Smcpowers   }
4827*5697Smcpowers   if (!pos)
4828*5697Smcpowers     str[pos++] = 0;
4829*5697Smcpowers   return pos;
4830*5697Smcpowers } /* end mp_to_signed_octets() */
4831*5697Smcpowers /* }}} */
4832*5697Smcpowers 
4833*5697Smcpowers /* {{{ mp_to_fixlen_octets(mp, str) */
4834*5697Smcpowers /* output a buffer of big endian octets exactly as long as requested. */
4835*5697Smcpowers mp_err
4836*5697Smcpowers mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)
4837*5697Smcpowers {
4838*5697Smcpowers   int  ix, pos = 0;
4839*5697Smcpowers   int  bytes;
4840*5697Smcpowers 
4841*5697Smcpowers   ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);
4842*5697Smcpowers 
4843*5697Smcpowers   bytes = mp_unsigned_octet_size(mp);
4844*5697Smcpowers   ARGCHK(bytes <= length, MP_BADARG);
4845*5697Smcpowers 
4846*5697Smcpowers   /* place any needed leading zeros */
4847*5697Smcpowers   for (;length > bytes; --length) {
4848*5697Smcpowers 	*str++ = 0;
4849*5697Smcpowers   }
4850*5697Smcpowers 
4851*5697Smcpowers   /* Iterate over each digit... */
4852*5697Smcpowers   for(ix = USED(mp) - 1; ix >= 0; ix--) {
4853*5697Smcpowers     mp_digit  d = DIGIT(mp, ix);
4854*5697Smcpowers     int       jx;
4855*5697Smcpowers 
4856*5697Smcpowers     /* Unpack digit bytes, high order first */
4857*5697Smcpowers     for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {
4858*5697Smcpowers       unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));
4859*5697Smcpowers       if (!pos && !x)	/* suppress leading zeros */
4860*5697Smcpowers 	continue;
4861*5697Smcpowers       str[pos++] = x;
4862*5697Smcpowers     }
4863*5697Smcpowers   }
4864*5697Smcpowers   if (!pos)
4865*5697Smcpowers     str[pos++] = 0;
4866*5697Smcpowers   return MP_OKAY;
4867*5697Smcpowers } /* end mp_to_fixlen_octets() */
4868*5697Smcpowers /* }}} */
4869*5697Smcpowers 
4870*5697Smcpowers 
4871*5697Smcpowers /*------------------------------------------------------------------------*/
4872*5697Smcpowers /* HERE THERE BE DRAGONS                                                  */
4873