Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/sun/security/ec/impl/mpi.c
38918 views
/*1* Copyright (c) 2007, 2020, Oracle and/or its affiliates. All rights reserved.2* Use is subject to license terms.3*4* This library is free software; you can redistribute it and/or5* modify it under the terms of the GNU Lesser General Public6* License as published by the Free Software Foundation; either7* version 2.1 of the License, or (at your option) any later version.8*9* This library is distributed in the hope that it will be useful,10* but WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12* Lesser General Public License for more details.13*14* You should have received a copy of the GNU Lesser General Public License15* along with this library; if not, write to the Free Software Foundation,16* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/* *********************************************************************24*25* The Original Code is the MPI Arbitrary Precision Integer Arithmetic library.26*27* The Initial Developer of the Original Code is28* Michael J. Fromberger.29* Portions created by the Initial Developer are Copyright (C) 199830* the Initial Developer. All Rights Reserved.31*32* Contributor(s):33* Netscape Communications Corporation34* Douglas Stebila <[email protected]> of Sun Laboratories.35*36* Last Modified Date from the Original Code: Nov 201937*********************************************************************** */3839/* Arbitrary precision integer arithmetic library */4041#include "mpi-priv.h"42#if defined(OSF1)43#include <c_asm.h>44#endif4546#if MP_LOGTAB47/*48A table of the logs of 2 for various bases (the 0 and 1 entries of49this table are meaningless and should not be referenced).5051This table is used to compute output lengths for the mp_toradix()52function. Since a number n in radix r takes up about log_r(n)53digits, we estimate the output size by taking the least integer54greater than log_r(n), where:5556log_r(n) = log_2(n) * log_r(2)5758This table, therefore, is a table of log_r(2) for 2 <= r <= 36,59which are the output bases supported.60*/61#include "logtab.h"62#endif6364/* {{{ Constant strings */6566/* Constant strings returned by mp_strerror() */67static const char *mp_err_string[] = {68"unknown result code", /* say what? */69"boolean true", /* MP_OKAY, MP_YES */70"boolean false", /* MP_NO */71"out of memory", /* MP_MEM */72"argument out of range", /* MP_RANGE */73"invalid input parameter", /* MP_BADARG */74"result is undefined" /* MP_UNDEF */75};7677/* Value to digit maps for radix conversion */7879/* s_dmap_1 - standard digits and letters */80static const char *s_dmap_1 =81"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";8283/* }}} */8485unsigned long mp_allocs;86unsigned long mp_frees;87unsigned long mp_copies;8889/* {{{ Default precision manipulation */9091/* Default precision for newly created mp_int's */92static mp_size s_mp_defprec = MP_DEFPREC;9394mp_size mp_get_prec(void)95{96return s_mp_defprec;9798} /* end mp_get_prec() */99100void mp_set_prec(mp_size prec)101{102if(prec == 0)103s_mp_defprec = MP_DEFPREC;104else105s_mp_defprec = prec;106107} /* end mp_set_prec() */108109/* }}} */110111/*------------------------------------------------------------------------*/112/* {{{ mp_init(mp, kmflag) */113114/*115mp_init(mp, kmflag)116117Initialize a new zero-valued mp_int. Returns MP_OKAY if successful,118MP_MEM if memory could not be allocated for the structure.119*/120121mp_err mp_init(mp_int *mp, int kmflag)122{123return mp_init_size(mp, s_mp_defprec, kmflag);124125} /* end mp_init() */126127/* }}} */128129/* {{{ mp_init_size(mp, prec, kmflag) */130131/*132mp_init_size(mp, prec, kmflag)133134Initialize a new zero-valued mp_int with at least the given135precision; returns MP_OKAY if successful, or MP_MEM if memory could136not be allocated for the structure.137*/138139mp_err mp_init_size(mp_int *mp, mp_size prec, int kmflag)140{141ARGCHK(mp != NULL && prec > 0, MP_BADARG);142143prec = MP_ROUNDUP(prec, s_mp_defprec);144if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit), kmflag)) == NULL)145return MP_MEM;146147SIGN(mp) = ZPOS;148USED(mp) = 1;149ALLOC(mp) = prec;150151return MP_OKAY;152153} /* end mp_init_size() */154155/* }}} */156157/* {{{ mp_init_copy(mp, from) */158159/*160mp_init_copy(mp, from)161162Initialize mp as an exact copy of from. Returns MP_OKAY if163successful, MP_MEM if memory could not be allocated for the new164structure.165*/166167mp_err mp_init_copy(mp_int *mp, const mp_int *from)168{169ARGCHK(mp != NULL && from != NULL, MP_BADARG);170171if(mp == from)172return MP_OKAY;173174if((DIGITS(mp) = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)175return MP_MEM;176177s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));178USED(mp) = USED(from);179ALLOC(mp) = ALLOC(from);180SIGN(mp) = SIGN(from);181182#ifndef _WIN32183FLAG(mp) = FLAG(from);184#endif /* _WIN32 */185186return MP_OKAY;187188} /* end mp_init_copy() */189190/* }}} */191192/* {{{ mp_copy(from, to) */193194/*195mp_copy(from, to)196197Copies the mp_int 'from' to the mp_int 'to'. It is presumed that198'to' has already been initialized (if not, use mp_init_copy()199instead). If 'from' and 'to' are identical, nothing happens.200*/201202mp_err mp_copy(const mp_int *from, mp_int *to)203{204ARGCHK(from != NULL && to != NULL, MP_BADARG);205206if(from == to)207return MP_OKAY;208209++mp_copies;210{ /* copy */211mp_digit *tmp;212213/*214If the allocated buffer in 'to' already has enough space to hold215all the used digits of 'from', we'll re-use it to avoid hitting216the memory allocater more than necessary; otherwise, we'd have217to grow anyway, so we just allocate a hunk and make the copy as218usual219*/220if(ALLOC(to) >= USED(from)) {221s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));222s_mp_copy(DIGITS(from), DIGITS(to), USED(from));223224} else {225if((tmp = s_mp_alloc(ALLOC(from), sizeof(mp_digit), FLAG(from))) == NULL)226return MP_MEM;227228s_mp_copy(DIGITS(from), tmp, USED(from));229230if(DIGITS(to) != NULL) {231#if MP_CRYPTO232s_mp_setz(DIGITS(to), ALLOC(to));233#endif234s_mp_free(DIGITS(to), ALLOC(to));235}236237DIGITS(to) = tmp;238ALLOC(to) = ALLOC(from);239}240241/* Copy the precision and sign from the original */242USED(to) = USED(from);243SIGN(to) = SIGN(from);244} /* end copy */245246return MP_OKAY;247248} /* end mp_copy() */249250/* }}} */251252/* {{{ mp_exch(mp1, mp2) */253254/*255mp_exch(mp1, mp2)256257Exchange mp1 and mp2 without allocating any intermediate memory258(well, unless you count the stack space needed for this call and the259locals it creates...). This cannot fail.260*/261262void mp_exch(mp_int *mp1, mp_int *mp2)263{264#if MP_ARGCHK == 2265assert(mp1 != NULL && mp2 != NULL);266#else267if(mp1 == NULL || mp2 == NULL)268return;269#endif270271s_mp_exch(mp1, mp2);272273} /* end mp_exch() */274275/* }}} */276277/* {{{ mp_clear(mp) */278279/*280mp_clear(mp)281282Release the storage used by an mp_int, and void its fields so that283if someone calls mp_clear() again for the same int later, we won't284get tollchocked.285*/286287void mp_clear(mp_int *mp)288{289if(mp == NULL)290return;291292if(DIGITS(mp) != NULL) {293#if MP_CRYPTO294s_mp_setz(DIGITS(mp), ALLOC(mp));295#endif296s_mp_free(DIGITS(mp), ALLOC(mp));297DIGITS(mp) = NULL;298}299300USED(mp) = 0;301ALLOC(mp) = 0;302303} /* end mp_clear() */304305/* }}} */306307/* {{{ mp_zero(mp) */308309/*310mp_zero(mp)311312Set mp to zero. Does not change the allocated size of the structure,313and therefore cannot fail (except on a bad argument, which we ignore)314*/315void mp_zero(mp_int *mp)316{317if(mp == NULL)318return;319320s_mp_setz(DIGITS(mp), ALLOC(mp));321USED(mp) = 1;322SIGN(mp) = ZPOS;323324} /* end mp_zero() */325326/* }}} */327328/* {{{ mp_set(mp, d) */329330void mp_set(mp_int *mp, mp_digit d)331{332if(mp == NULL)333return;334335mp_zero(mp);336DIGIT(mp, 0) = d;337338} /* end mp_set() */339340/* }}} */341342/* {{{ mp_set_int(mp, z) */343344mp_err mp_set_int(mp_int *mp, long z)345{346int ix;347unsigned long v = labs(z);348mp_err res;349350ARGCHK(mp != NULL, MP_BADARG);351352mp_zero(mp);353if(z == 0)354return MP_OKAY; /* shortcut for zero */355356if (sizeof v <= sizeof(mp_digit)) {357DIGIT(mp,0) = v;358} else {359for (ix = sizeof(long) - 1; ix >= 0; ix--) {360if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)361return res;362363res = s_mp_add_d(mp, (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));364if (res != MP_OKAY)365return res;366}367}368if(z < 0)369SIGN(mp) = NEG;370371return MP_OKAY;372373} /* end mp_set_int() */374375/* }}} */376377/* {{{ mp_set_ulong(mp, z) */378379mp_err mp_set_ulong(mp_int *mp, unsigned long z)380{381int ix;382mp_err res;383384ARGCHK(mp != NULL, MP_BADARG);385386mp_zero(mp);387if(z == 0)388return MP_OKAY; /* shortcut for zero */389390if (sizeof z <= sizeof(mp_digit)) {391DIGIT(mp,0) = z;392} else {393for (ix = sizeof(long) - 1; ix >= 0; ix--) {394if ((res = s_mp_mul_d(mp, (UCHAR_MAX + 1))) != MP_OKAY)395return res;396397res = s_mp_add_d(mp, (mp_digit)((z >> (ix * CHAR_BIT)) & UCHAR_MAX));398if (res != MP_OKAY)399return res;400}401}402return MP_OKAY;403} /* end mp_set_ulong() */404405/* }}} */406407/*------------------------------------------------------------------------*/408/* {{{ Digit arithmetic */409410/* {{{ mp_add_d(a, d, b) */411412/*413mp_add_d(a, d, b)414415Compute the sum b = a + d, for a single digit d. Respects the sign of416its primary addend (single digits are unsigned anyway).417*/418419mp_err mp_add_d(const mp_int *a, mp_digit d, mp_int *b)420{421mp_int tmp;422mp_err res;423424ARGCHK(a != NULL && b != NULL, MP_BADARG);425426if((res = mp_init_copy(&tmp, a)) != MP_OKAY)427return res;428429if(SIGN(&tmp) == ZPOS) {430if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)431goto CLEANUP;432} else if(s_mp_cmp_d(&tmp, d) >= 0) {433if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)434goto CLEANUP;435} else {436mp_neg(&tmp, &tmp);437438DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);439}440441if(s_mp_cmp_d(&tmp, 0) == 0)442SIGN(&tmp) = ZPOS;443444s_mp_exch(&tmp, b);445446CLEANUP:447mp_clear(&tmp);448return res;449450} /* end mp_add_d() */451452/* }}} */453454/* {{{ mp_sub_d(a, d, b) */455456/*457mp_sub_d(a, d, b)458459Compute the difference b = a - d, for a single digit d. Respects the460sign of its subtrahend (single digits are unsigned anyway).461*/462463mp_err mp_sub_d(const mp_int *a, mp_digit d, mp_int *b)464{465mp_int tmp;466mp_err res;467468ARGCHK(a != NULL && b != NULL, MP_BADARG);469470if((res = mp_init_copy(&tmp, a)) != MP_OKAY)471return res;472473if(SIGN(&tmp) == NEG) {474if((res = s_mp_add_d(&tmp, d)) != MP_OKAY)475goto CLEANUP;476} else if(s_mp_cmp_d(&tmp, d) >= 0) {477if((res = s_mp_sub_d(&tmp, d)) != MP_OKAY)478goto CLEANUP;479} else {480mp_neg(&tmp, &tmp);481482DIGIT(&tmp, 0) = d - DIGIT(&tmp, 0);483SIGN(&tmp) = NEG;484}485486if(s_mp_cmp_d(&tmp, 0) == 0)487SIGN(&tmp) = ZPOS;488489s_mp_exch(&tmp, b);490491CLEANUP:492mp_clear(&tmp);493return res;494495} /* end mp_sub_d() */496497/* }}} */498499/* {{{ mp_mul_d(a, d, b) */500501/*502mp_mul_d(a, d, b)503504Compute the product b = a * d, for a single digit d. Respects the sign505of its multiplicand (single digits are unsigned anyway)506*/507508mp_err mp_mul_d(const mp_int *a, mp_digit d, mp_int *b)509{510mp_err res;511512ARGCHK(a != NULL && b != NULL, MP_BADARG);513514if(d == 0) {515mp_zero(b);516return MP_OKAY;517}518519if((res = mp_copy(a, b)) != MP_OKAY)520return res;521522res = s_mp_mul_d(b, d);523524return res;525526} /* end mp_mul_d() */527528/* }}} */529530/* {{{ mp_mul_2(a, c) */531532mp_err mp_mul_2(const mp_int *a, mp_int *c)533{534mp_err res;535536ARGCHK(a != NULL && c != NULL, MP_BADARG);537538if((res = mp_copy(a, c)) != MP_OKAY)539return res;540541return s_mp_mul_2(c);542543} /* end mp_mul_2() */544545/* }}} */546547/* {{{ mp_div_d(a, d, q, r) */548549/*550mp_div_d(a, d, q, r)551552Compute the quotient q = a / d and remainder r = a mod d, for a553single digit d. Respects the sign of its divisor (single digits are554unsigned anyway).555*/556557mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)558{559mp_err res;560mp_int qp;561mp_digit rem;562int pow;563564ARGCHK(a != NULL, MP_BADARG);565566if(d == 0)567return MP_RANGE;568569/* Shortcut for powers of two ... */570if((pow = s_mp_ispow2d(d)) >= 0) {571mp_digit mask;572573mask = ((mp_digit)1 << pow) - 1;574rem = DIGIT(a, 0) & mask;575576if(q) {577mp_copy(a, q);578s_mp_div_2d(q, pow);579}580581if(r)582*r = rem;583584return MP_OKAY;585}586587if((res = mp_init_copy(&qp, a)) != MP_OKAY)588return res;589590res = s_mp_div_d(&qp, d, &rem);591592if(s_mp_cmp_d(&qp, 0) == 0)593SIGN(q) = ZPOS;594595if(r)596*r = rem;597598if(q)599s_mp_exch(&qp, q);600601mp_clear(&qp);602return res;603604} /* end mp_div_d() */605606/* }}} */607608/* {{{ mp_div_2(a, c) */609610/*611mp_div_2(a, c)612613Compute c = a / 2, disregarding the remainder.614*/615616mp_err mp_div_2(const mp_int *a, mp_int *c)617{618mp_err res;619620ARGCHK(a != NULL && c != NULL, MP_BADARG);621622if((res = mp_copy(a, c)) != MP_OKAY)623return res;624625s_mp_div_2(c);626627return MP_OKAY;628629} /* end mp_div_2() */630631/* }}} */632633/* {{{ mp_expt_d(a, d, b) */634635mp_err mp_expt_d(const mp_int *a, mp_digit d, mp_int *c)636{637mp_int s, x;638mp_err res;639640ARGCHK(a != NULL && c != NULL, MP_BADARG);641642if((res = mp_init(&s, FLAG(a))) != MP_OKAY)643return res;644if((res = mp_init_copy(&x, a)) != MP_OKAY)645goto X;646647DIGIT(&s, 0) = 1;648649while(d != 0) {650if(d & 1) {651if((res = s_mp_mul(&s, &x)) != MP_OKAY)652goto CLEANUP;653}654655d /= 2;656657if((res = s_mp_sqr(&x)) != MP_OKAY)658goto CLEANUP;659}660661s_mp_exch(&s, c);662663CLEANUP:664mp_clear(&x);665X:666mp_clear(&s);667668return res;669670} /* end mp_expt_d() */671672/* }}} */673674/* }}} */675676/*------------------------------------------------------------------------*/677/* {{{ Full arithmetic */678679/* {{{ mp_abs(a, b) */680681/*682mp_abs(a, b)683684Compute b = |a|. 'a' and 'b' may be identical.685*/686687mp_err mp_abs(const mp_int *a, mp_int *b)688{689mp_err res;690691ARGCHK(a != NULL && b != NULL, MP_BADARG);692693if((res = mp_copy(a, b)) != MP_OKAY)694return res;695696SIGN(b) = ZPOS;697698return MP_OKAY;699700} /* end mp_abs() */701702/* }}} */703704/* {{{ mp_neg(a, b) */705706/*707mp_neg(a, b)708709Compute b = -a. 'a' and 'b' may be identical.710*/711712mp_err mp_neg(const mp_int *a, mp_int *b)713{714mp_err res;715716ARGCHK(a != NULL && b != NULL, MP_BADARG);717718if((res = mp_copy(a, b)) != MP_OKAY)719return res;720721if(s_mp_cmp_d(b, 0) == MP_EQ)722SIGN(b) = ZPOS;723else724SIGN(b) = (SIGN(b) == NEG) ? ZPOS : NEG;725726return MP_OKAY;727728} /* end mp_neg() */729730/* }}} */731732/* {{{ mp_add(a, b, c) */733734/*735mp_add(a, b, c)736737Compute c = a + b. All parameters may be identical.738*/739740mp_err mp_add(const mp_int *a, const mp_int *b, mp_int *c)741{742mp_err res;743744ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);745746if(SIGN(a) == SIGN(b)) { /* same sign: add values, keep sign */747MP_CHECKOK( s_mp_add_3arg(a, b, c) );748} else if(s_mp_cmp(a, b) >= 0) { /* different sign: |a| >= |b| */749MP_CHECKOK( s_mp_sub_3arg(a, b, c) );750} else { /* different sign: |a| < |b| */751MP_CHECKOK( s_mp_sub_3arg(b, a, c) );752}753754if (s_mp_cmp_d(c, 0) == MP_EQ)755SIGN(c) = ZPOS;756757CLEANUP:758return res;759760} /* end mp_add() */761762/* }}} */763764/* {{{ mp_sub(a, b, c) */765766/*767mp_sub(a, b, c)768769Compute c = a - b. All parameters may be identical.770*/771772mp_err mp_sub(const mp_int *a, const mp_int *b, mp_int *c)773{774mp_err res;775int magDiff;776777ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);778779if (a == b) {780mp_zero(c);781return MP_OKAY;782}783784if (MP_SIGN(a) != MP_SIGN(b)) {785MP_CHECKOK( s_mp_add_3arg(a, b, c) );786} else if (!(magDiff = s_mp_cmp(a, b))) {787mp_zero(c);788res = MP_OKAY;789} else if (magDiff > 0) {790MP_CHECKOK( s_mp_sub_3arg(a, b, c) );791} else {792MP_CHECKOK( s_mp_sub_3arg(b, a, c) );793MP_SIGN(c) = !MP_SIGN(a);794}795796if (s_mp_cmp_d(c, 0) == MP_EQ)797MP_SIGN(c) = MP_ZPOS;798799CLEANUP:800return res;801802} /* end mp_sub() */803804/* }}} */805806/* {{{ mp_mul(a, b, c) */807808/*809mp_mul(a, b, c)810811Compute c = a * b. All parameters may be identical.812*/813mp_err mp_mul(const mp_int *a, const mp_int *b, mp_int * c)814{815mp_digit *pb;816mp_int tmp;817mp_err res;818mp_size ib;819mp_size useda, usedb;820821ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);822823if (a == c) {824if ((res = mp_init_copy(&tmp, a)) != MP_OKAY)825return res;826if (a == b)827b = &tmp;828a = &tmp;829} else if (b == c) {830if ((res = mp_init_copy(&tmp, b)) != MP_OKAY)831return res;832b = &tmp;833} else {834MP_DIGITS(&tmp) = 0;835}836837if (MP_USED(a) < MP_USED(b)) {838const mp_int *xch = b; /* switch a and b, to do fewer outer loops */839b = a;840a = xch;841}842843MP_USED(c) = 1; MP_DIGIT(c, 0) = 0;844if((res = s_mp_pad(c, USED(a) + USED(b))) != MP_OKAY)845goto CLEANUP;846847#ifdef NSS_USE_COMBA848if ((MP_USED(a) == MP_USED(b)) && IS_POWER_OF_2(MP_USED(b))) {849if (MP_USED(a) == 4) {850s_mp_mul_comba_4(a, b, c);851goto CLEANUP;852}853if (MP_USED(a) == 8) {854s_mp_mul_comba_8(a, b, c);855goto CLEANUP;856}857if (MP_USED(a) == 16) {858s_mp_mul_comba_16(a, b, c);859goto CLEANUP;860}861if (MP_USED(a) == 32) {862s_mp_mul_comba_32(a, b, c);863goto CLEANUP;864}865}866#endif867868pb = MP_DIGITS(b);869s_mpv_mul_d(MP_DIGITS(a), MP_USED(a), *pb++, MP_DIGITS(c));870871/* Outer loop: Digits of b */872useda = MP_USED(a);873usedb = MP_USED(b);874for (ib = 1; ib < usedb; ib++) {875mp_digit b_i = *pb++;876877/* Inner product: Digits of a */878if (b_i)879s_mpv_mul_d_add(MP_DIGITS(a), useda, b_i, MP_DIGITS(c) + ib);880else881MP_DIGIT(c, ib + useda) = b_i;882}883884s_mp_clamp(c);885886if(SIGN(a) == SIGN(b) || s_mp_cmp_d(c, 0) == MP_EQ)887SIGN(c) = ZPOS;888else889SIGN(c) = NEG;890891CLEANUP:892mp_clear(&tmp);893return res;894} /* end mp_mul() */895896/* }}} */897898/* {{{ mp_sqr(a, sqr) */899900#if MP_SQUARE901/*902Computes the square of a. This can be done more903efficiently than a general multiplication, because many of the904computation steps are redundant when squaring. The inner product905step is a bit more complicated, but we save a fair number of906iterations of the multiplication loop.907*/908909/* sqr = a^2; Caller provides both a and tmp; */910mp_err mp_sqr(const mp_int *a, mp_int *sqr)911{912mp_digit *pa;913mp_digit d;914mp_err res;915mp_size ix;916mp_int tmp;917int count;918919ARGCHK(a != NULL && sqr != NULL, MP_BADARG);920921if (a == sqr) {922if((res = mp_init_copy(&tmp, a)) != MP_OKAY)923return res;924a = &tmp;925} else {926DIGITS(&tmp) = 0;927res = MP_OKAY;928}929930ix = 2 * MP_USED(a);931if (ix > MP_ALLOC(sqr)) {932MP_USED(sqr) = 1;933MP_CHECKOK( s_mp_grow(sqr, ix) );934}935MP_USED(sqr) = ix;936MP_DIGIT(sqr, 0) = 0;937938#ifdef NSS_USE_COMBA939if (IS_POWER_OF_2(MP_USED(a))) {940if (MP_USED(a) == 4) {941s_mp_sqr_comba_4(a, sqr);942goto CLEANUP;943}944if (MP_USED(a) == 8) {945s_mp_sqr_comba_8(a, sqr);946goto CLEANUP;947}948if (MP_USED(a) == 16) {949s_mp_sqr_comba_16(a, sqr);950goto CLEANUP;951}952if (MP_USED(a) == 32) {953s_mp_sqr_comba_32(a, sqr);954goto CLEANUP;955}956}957#endif958959pa = MP_DIGITS(a);960count = MP_USED(a) - 1;961if (count > 0) {962d = *pa++;963s_mpv_mul_d(pa, count, d, MP_DIGITS(sqr) + 1);964for (ix = 3; --count > 0; ix += 2) {965d = *pa++;966s_mpv_mul_d_add(pa, count, d, MP_DIGITS(sqr) + ix);967} /* for(ix ...) */968MP_DIGIT(sqr, MP_USED(sqr)-1) = 0; /* above loop stopped short of this. */969970/* now sqr *= 2 */971s_mp_mul_2(sqr);972} else {973MP_DIGIT(sqr, 1) = 0;974}975976/* now add the squares of the digits of a to sqr. */977s_mpv_sqr_add_prop(MP_DIGITS(a), MP_USED(a), MP_DIGITS(sqr));978979SIGN(sqr) = ZPOS;980s_mp_clamp(sqr);981982CLEANUP:983mp_clear(&tmp);984return res;985986} /* end mp_sqr() */987#endif988989/* }}} */990991/* {{{ mp_div(a, b, q, r) */992993/*994mp_div(a, b, q, r)995996Compute q = a / b and r = a mod b. Input parameters may be re-used997as output parameters. If q or r is NULL, that portion of the998computation will be discarded (although it will still be computed)999*/1000mp_err mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r)1001{1002mp_err res;1003mp_int *pQ, *pR;1004mp_int qtmp, rtmp, btmp;1005int cmp;1006mp_sign signA;1007mp_sign signB;10081009ARGCHK(a != NULL && b != NULL, MP_BADARG);10101011signA = MP_SIGN(a);1012signB = MP_SIGN(b);10131014if(mp_cmp_z(b) == MP_EQ)1015return MP_RANGE;10161017DIGITS(&qtmp) = 0;1018DIGITS(&rtmp) = 0;1019DIGITS(&btmp) = 0;10201021/* Set up some temporaries... */1022if (!r || r == a || r == b) {1023MP_CHECKOK( mp_init_copy(&rtmp, a) );1024pR = &rtmp;1025} else {1026MP_CHECKOK( mp_copy(a, r) );1027pR = r;1028}10291030if (!q || q == a || q == b) {1031MP_CHECKOK( mp_init_size(&qtmp, MP_USED(a), FLAG(a)) );1032pQ = &qtmp;1033} else {1034MP_CHECKOK( s_mp_pad(q, MP_USED(a)) );1035pQ = q;1036mp_zero(pQ);1037}10381039/*1040If |a| <= |b|, we can compute the solution without division;1041otherwise, we actually do the work required.1042*/1043if ((cmp = s_mp_cmp(a, b)) <= 0) {1044if (cmp) {1045/* r was set to a above. */1046mp_zero(pQ);1047} else {1048mp_set(pQ, 1);1049mp_zero(pR);1050}1051} else {1052MP_CHECKOK( mp_init_copy(&btmp, b) );1053MP_CHECKOK( s_mp_div(pR, &btmp, pQ) );1054}10551056/* Compute the signs for the output */1057MP_SIGN(pR) = signA; /* Sr = Sa */1058/* Sq = ZPOS if Sa == Sb */ /* Sq = NEG if Sa != Sb */1059MP_SIGN(pQ) = (signA == signB) ? ZPOS : NEG;10601061if(s_mp_cmp_d(pQ, 0) == MP_EQ)1062SIGN(pQ) = ZPOS;1063if(s_mp_cmp_d(pR, 0) == MP_EQ)1064SIGN(pR) = ZPOS;10651066/* Copy output, if it is needed */1067if(q && q != pQ)1068s_mp_exch(pQ, q);10691070if(r && r != pR)1071s_mp_exch(pR, r);10721073CLEANUP:1074mp_clear(&btmp);1075mp_clear(&rtmp);1076mp_clear(&qtmp);10771078return res;10791080} /* end mp_div() */10811082/* }}} */10831084/* {{{ mp_div_2d(a, d, q, r) */10851086mp_err mp_div_2d(const mp_int *a, mp_digit d, mp_int *q, mp_int *r)1087{1088mp_err res;10891090ARGCHK(a != NULL, MP_BADARG);10911092if(q) {1093if((res = mp_copy(a, q)) != MP_OKAY)1094return res;1095}1096if(r) {1097if((res = mp_copy(a, r)) != MP_OKAY)1098return res;1099}1100if(q) {1101s_mp_div_2d(q, d);1102}1103if(r) {1104s_mp_mod_2d(r, d);1105}11061107return MP_OKAY;11081109} /* end mp_div_2d() */11101111/* }}} */11121113/* {{{ mp_expt(a, b, c) */11141115/*1116mp_expt(a, b, c)11171118Compute c = a ** b, that is, raise a to the b power. Uses a1119standard iterative square-and-multiply technique.1120*/11211122mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)1123{1124mp_int s, x;1125mp_err res;1126mp_digit d;1127unsigned int dig, bit;11281129ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);11301131if(mp_cmp_z(b) < 0)1132return MP_RANGE;11331134if((res = mp_init(&s, FLAG(a))) != MP_OKAY)1135return res;11361137mp_set(&s, 1);11381139if((res = mp_init_copy(&x, a)) != MP_OKAY)1140goto X;11411142/* Loop over low-order digits in ascending order */1143for(dig = 0; dig < (USED(b) - 1); dig++) {1144d = DIGIT(b, dig);11451146/* Loop over bits of each non-maximal digit */1147for(bit = 0; bit < DIGIT_BIT; bit++) {1148if(d & 1) {1149if((res = s_mp_mul(&s, &x)) != MP_OKAY)1150goto CLEANUP;1151}11521153d >>= 1;11541155if((res = s_mp_sqr(&x)) != MP_OKAY)1156goto CLEANUP;1157}1158}11591160/* Consider now the last digit... */1161d = DIGIT(b, dig);11621163while(d) {1164if(d & 1) {1165if((res = s_mp_mul(&s, &x)) != MP_OKAY)1166goto CLEANUP;1167}11681169d >>= 1;11701171if((res = s_mp_sqr(&x)) != MP_OKAY)1172goto CLEANUP;1173}11741175if(mp_iseven(b))1176SIGN(&s) = SIGN(a);11771178res = mp_copy(&s, c);11791180CLEANUP:1181mp_clear(&x);1182X:1183mp_clear(&s);11841185return res;11861187} /* end mp_expt() */11881189/* }}} */11901191/* {{{ mp_2expt(a, k) */11921193/* Compute a = 2^k */11941195mp_err mp_2expt(mp_int *a, mp_digit k)1196{1197ARGCHK(a != NULL, MP_BADARG);11981199return s_mp_2expt(a, k);12001201} /* end mp_2expt() */12021203/* }}} */12041205/* {{{ mp_mod(a, m, c) */12061207/*1208mp_mod(a, m, c)12091210Compute c = a (mod m). Result will always be 0 <= c < m.1211*/12121213mp_err mp_mod(const mp_int *a, const mp_int *m, mp_int *c)1214{1215mp_err res;1216int mag;12171218ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);12191220if(SIGN(m) == NEG)1221return MP_RANGE;12221223/*1224If |a| > m, we need to divide to get the remainder and take the1225absolute value.12261227If |a| < m, we don't need to do any division, just copy and adjust1228the sign (if a is negative).12291230If |a| == m, we can simply set the result to zero.12311232This order is intended to minimize the average path length of the1233comparison chain on common workloads -- the most frequent cases are1234that |a| != m, so we do those first.1235*/1236if((mag = s_mp_cmp(a, m)) > 0) {1237if((res = mp_div(a, m, NULL, c)) != MP_OKAY)1238return res;12391240if(SIGN(c) == NEG) {1241if((res = mp_add(c, m, c)) != MP_OKAY)1242return res;1243}12441245} else if(mag < 0) {1246if((res = mp_copy(a, c)) != MP_OKAY)1247return res;12481249if(mp_cmp_z(a) < 0) {1250if((res = mp_add(c, m, c)) != MP_OKAY)1251return res;12521253}12541255} else {1256mp_zero(c);12571258}12591260return MP_OKAY;12611262} /* end mp_mod() */12631264/* }}} */12651266/* {{{ mp_mod_d(a, d, c) */12671268/*1269mp_mod_d(a, d, c)12701271Compute c = a (mod d). Result will always be 0 <= c < d1272*/1273mp_err mp_mod_d(const mp_int *a, mp_digit d, mp_digit *c)1274{1275mp_err res;1276mp_digit rem;12771278ARGCHK(a != NULL && c != NULL, MP_BADARG);12791280if(s_mp_cmp_d(a, d) > 0) {1281if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)1282return res;12831284} else {1285if(SIGN(a) == NEG)1286rem = d - DIGIT(a, 0);1287else1288rem = DIGIT(a, 0);1289}12901291if(c)1292*c = rem;12931294return MP_OKAY;12951296} /* end mp_mod_d() */12971298/* }}} */12991300/* {{{ mp_sqrt(a, b) */13011302/*1303mp_sqrt(a, b)13041305Compute the integer square root of a, and store the result in b.1306Uses an integer-arithmetic version of Newton's iterative linear1307approximation technique to determine this value; the result has the1308following two properties:13091310b^2 <= a1311(b+1)^2 >= a13121313It is a range error to pass a negative value.1314*/1315mp_err mp_sqrt(const mp_int *a, mp_int *b)1316{1317mp_int x, t;1318mp_err res;1319mp_size used;13201321ARGCHK(a != NULL && b != NULL, MP_BADARG);13221323/* Cannot take square root of a negative value */1324if(SIGN(a) == NEG)1325return MP_RANGE;13261327/* Special cases for zero and one, trivial */1328if(mp_cmp_d(a, 1) <= 0)1329return mp_copy(a, b);13301331/* Initialize the temporaries we'll use below */1332if((res = mp_init_size(&t, USED(a), FLAG(a))) != MP_OKAY)1333return res;13341335/* Compute an initial guess for the iteration as a itself */1336if((res = mp_init_copy(&x, a)) != MP_OKAY)1337goto X;13381339used = MP_USED(&x);1340if (used > 1) {1341s_mp_rshd(&x, used / 2);1342}13431344for(;;) {1345/* t = (x * x) - a */1346mp_copy(&x, &t); /* can't fail, t is big enough for original x */1347if((res = mp_sqr(&t, &t)) != MP_OKAY ||1348(res = mp_sub(&t, a, &t)) != MP_OKAY)1349goto CLEANUP;13501351/* t = t / 2x */1352s_mp_mul_2(&x);1353if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)1354goto CLEANUP;1355s_mp_div_2(&x);13561357/* Terminate the loop, if the quotient is zero */1358if(mp_cmp_z(&t) == MP_EQ)1359break;13601361/* x = x - t */1362if((res = mp_sub(&x, &t, &x)) != MP_OKAY)1363goto CLEANUP;13641365}13661367/* Copy result to output parameter */1368mp_sub_d(&x, 1, &x);1369s_mp_exch(&x, b);13701371CLEANUP:1372mp_clear(&x);1373X:1374mp_clear(&t);13751376return res;13771378} /* end mp_sqrt() */13791380/* }}} */13811382/* }}} */13831384/*------------------------------------------------------------------------*/1385/* {{{ Modular arithmetic */13861387#if MP_MODARITH1388/* {{{ mp_addmod(a, b, m, c) */13891390/*1391mp_addmod(a, b, m, c)13921393Compute c = (a + b) mod m1394*/13951396mp_err mp_addmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)1397{1398mp_err res;13991400ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);14011402if((res = mp_add(a, b, c)) != MP_OKAY)1403return res;1404if((res = mp_mod(c, m, c)) != MP_OKAY)1405return res;14061407return MP_OKAY;14081409}14101411/* }}} */14121413/* {{{ mp_submod(a, b, m, c) */14141415/*1416mp_submod(a, b, m, c)14171418Compute c = (a - b) mod m1419*/14201421mp_err mp_submod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)1422{1423mp_err res;14241425ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);14261427if((res = mp_sub(a, b, c)) != MP_OKAY)1428return res;1429if((res = mp_mod(c, m, c)) != MP_OKAY)1430return res;14311432return MP_OKAY;14331434}14351436/* }}} */14371438/* {{{ mp_mulmod(a, b, m, c) */14391440/*1441mp_mulmod(a, b, m, c)14421443Compute c = (a * b) mod m1444*/14451446mp_err mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)1447{1448mp_err res;14491450ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);14511452if((res = mp_mul(a, b, c)) != MP_OKAY)1453return res;1454if((res = mp_mod(c, m, c)) != MP_OKAY)1455return res;14561457return MP_OKAY;14581459}14601461/* }}} */14621463/* {{{ mp_sqrmod(a, m, c) */14641465#if MP_SQUARE1466mp_err mp_sqrmod(const mp_int *a, const mp_int *m, mp_int *c)1467{1468mp_err res;14691470ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);14711472if((res = mp_sqr(a, c)) != MP_OKAY)1473return res;1474if((res = mp_mod(c, m, c)) != MP_OKAY)1475return res;14761477return MP_OKAY;14781479} /* end mp_sqrmod() */1480#endif14811482/* }}} */14831484/* {{{ s_mp_exptmod(a, b, m, c) */14851486/*1487s_mp_exptmod(a, b, m, c)14881489Compute c = (a ** b) mod m. Uses a standard square-and-multiply1490method with modular reductions at each step. (This is basically the1491same code as mp_expt(), except for the addition of the reductions)14921493The modular reductions are done using Barrett's algorithm (see1494s_mp_reduce() below for details)1495*/14961497mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c)1498{1499mp_int s, x, mu;1500mp_err res;1501mp_digit d;1502unsigned int dig, bit;15031504ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);15051506if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)1507return MP_RANGE;15081509if((res = mp_init(&s, FLAG(a))) != MP_OKAY)1510return res;1511if((res = mp_init_copy(&x, a)) != MP_OKAY ||1512(res = mp_mod(&x, m, &x)) != MP_OKAY)1513goto X;1514if((res = mp_init(&mu, FLAG(a))) != MP_OKAY)1515goto MU;15161517mp_set(&s, 1);15181519/* mu = b^2k / m */1520s_mp_add_d(&mu, 1);1521s_mp_lshd(&mu, 2 * USED(m));1522if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)1523goto CLEANUP;15241525/* Loop over digits of b in ascending order, except highest order */1526for(dig = 0; dig < (USED(b) - 1); dig++) {1527d = DIGIT(b, dig);15281529/* Loop over the bits of the lower-order digits */1530for(bit = 0; bit < DIGIT_BIT; bit++) {1531if(d & 1) {1532if((res = s_mp_mul(&s, &x)) != MP_OKAY)1533goto CLEANUP;1534if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)1535goto CLEANUP;1536}15371538d >>= 1;15391540if((res = s_mp_sqr(&x)) != MP_OKAY)1541goto CLEANUP;1542if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)1543goto CLEANUP;1544}1545}15461547/* Now do the last digit... */1548d = DIGIT(b, dig);15491550while(d) {1551if(d & 1) {1552if((res = s_mp_mul(&s, &x)) != MP_OKAY)1553goto CLEANUP;1554if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)1555goto CLEANUP;1556}15571558d >>= 1;15591560if((res = s_mp_sqr(&x)) != MP_OKAY)1561goto CLEANUP;1562if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)1563goto CLEANUP;1564}15651566s_mp_exch(&s, c);15671568CLEANUP:1569mp_clear(&mu);1570MU:1571mp_clear(&x);1572X:1573mp_clear(&s);15741575return res;15761577} /* end s_mp_exptmod() */15781579/* }}} */15801581/* {{{ mp_exptmod_d(a, d, m, c) */15821583mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c)1584{1585mp_int s, x;1586mp_err res;15871588ARGCHK(a != NULL && c != NULL, MP_BADARG);15891590if((res = mp_init(&s, FLAG(a))) != MP_OKAY)1591return res;1592if((res = mp_init_copy(&x, a)) != MP_OKAY)1593goto X;15941595mp_set(&s, 1);15961597while(d != 0) {1598if(d & 1) {1599if((res = s_mp_mul(&s, &x)) != MP_OKAY ||1600(res = mp_mod(&s, m, &s)) != MP_OKAY)1601goto CLEANUP;1602}16031604d /= 2;16051606if((res = s_mp_sqr(&x)) != MP_OKAY ||1607(res = mp_mod(&x, m, &x)) != MP_OKAY)1608goto CLEANUP;1609}16101611s_mp_exch(&s, c);16121613CLEANUP:1614mp_clear(&x);1615X:1616mp_clear(&s);16171618return res;16191620} /* end mp_exptmod_d() */16211622/* }}} */1623#endif /* if MP_MODARITH */16241625/* }}} */16261627/*------------------------------------------------------------------------*/1628/* {{{ Comparison functions */16291630/* {{{ mp_cmp_z(a) */16311632/*1633mp_cmp_z(a)16341635Compare a <=> 0. Returns <0 if a<0, 0 if a=0, >0 if a>0.1636*/16371638int mp_cmp_z(const mp_int *a)1639{1640if(SIGN(a) == NEG)1641return MP_LT;1642else if(USED(a) == 1 && DIGIT(a, 0) == 0)1643return MP_EQ;1644else1645return MP_GT;16461647} /* end mp_cmp_z() */16481649/* }}} */16501651/* {{{ mp_cmp_d(a, d) */16521653/*1654mp_cmp_d(a, d)16551656Compare a <=> d. Returns <0 if a<d, 0 if a=d, >0 if a>d1657*/16581659int mp_cmp_d(const mp_int *a, mp_digit d)1660{1661ARGCHK(a != NULL, MP_EQ);16621663if(SIGN(a) == NEG)1664return MP_LT;16651666return s_mp_cmp_d(a, d);16671668} /* end mp_cmp_d() */16691670/* }}} */16711672/* {{{ mp_cmp(a, b) */16731674int mp_cmp(const mp_int *a, const mp_int *b)1675{1676ARGCHK(a != NULL && b != NULL, MP_EQ);16771678if(SIGN(a) == SIGN(b)) {1679int mag;16801681if((mag = s_mp_cmp(a, b)) == MP_EQ)1682return MP_EQ;16831684if(SIGN(a) == ZPOS)1685return mag;1686else1687return -mag;16881689} else if(SIGN(a) == ZPOS) {1690return MP_GT;1691} else {1692return MP_LT;1693}16941695} /* end mp_cmp() */16961697/* }}} */16981699/* {{{ mp_cmp_mag(a, b) */17001701/*1702mp_cmp_mag(a, b)17031704Compares |a| <=> |b|, and returns an appropriate comparison result1705*/17061707int mp_cmp_mag(mp_int *a, mp_int *b)1708{1709ARGCHK(a != NULL && b != NULL, MP_EQ);17101711return s_mp_cmp(a, b);17121713} /* end mp_cmp_mag() */17141715/* }}} */17161717/* {{{ mp_cmp_int(a, z, kmflag) */17181719/*1720This just converts z to an mp_int, and uses the existing comparison1721routines. This is sort of inefficient, but it's not clear to me how1722frequently this wil get used anyway. For small positive constants,1723you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().1724*/1725int mp_cmp_int(const mp_int *a, long z, int kmflag)1726{1727mp_int tmp;1728int out;17291730ARGCHK(a != NULL, MP_EQ);17311732mp_init(&tmp, kmflag); mp_set_int(&tmp, z);1733out = mp_cmp(a, &tmp);1734mp_clear(&tmp);17351736return out;17371738} /* end mp_cmp_int() */17391740/* }}} */17411742/* {{{ mp_isodd(a) */17431744/*1745mp_isodd(a)17461747Returns a true (non-zero) value if a is odd, false (zero) otherwise.1748*/1749int mp_isodd(const mp_int *a)1750{1751ARGCHK(a != NULL, 0);17521753return (int)(DIGIT(a, 0) & 1);17541755} /* end mp_isodd() */17561757/* }}} */17581759/* {{{ mp_iseven(a) */17601761int mp_iseven(const mp_int *a)1762{1763return !mp_isodd(a);17641765} /* end mp_iseven() */17661767/* }}} */17681769/* }}} */17701771/*------------------------------------------------------------------------*/1772/* {{{ Number theoretic functions */17731774#if MP_NUMTH1775/* {{{ mp_gcd(a, b, c) */17761777/*1778Like the old mp_gcd() function, except computes the GCD using the1779binary algorithm due to Josef Stein in 1961 (via Knuth).1780*/1781mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)1782{1783mp_err res;1784mp_int u, v, t;1785mp_size k = 0;17861787ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);17881789if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)1790return MP_RANGE;1791if(mp_cmp_z(a) == MP_EQ) {1792return mp_copy(b, c);1793} else if(mp_cmp_z(b) == MP_EQ) {1794return mp_copy(a, c);1795}17961797if((res = mp_init(&t, FLAG(a))) != MP_OKAY)1798return res;1799if((res = mp_init_copy(&u, a)) != MP_OKAY)1800goto U;1801if((res = mp_init_copy(&v, b)) != MP_OKAY)1802goto V;18031804SIGN(&u) = ZPOS;1805SIGN(&v) = ZPOS;18061807/* Divide out common factors of 2 until at least 1 of a, b is even */1808while(mp_iseven(&u) && mp_iseven(&v)) {1809s_mp_div_2(&u);1810s_mp_div_2(&v);1811++k;1812}18131814/* Initialize t */1815if(mp_isodd(&u)) {1816if((res = mp_copy(&v, &t)) != MP_OKAY)1817goto CLEANUP;18181819/* t = -v */1820if(SIGN(&v) == ZPOS)1821SIGN(&t) = NEG;1822else1823SIGN(&t) = ZPOS;18241825} else {1826if((res = mp_copy(&u, &t)) != MP_OKAY)1827goto CLEANUP;18281829}18301831for(;;) {1832while(mp_iseven(&t)) {1833s_mp_div_2(&t);1834}18351836if(mp_cmp_z(&t) == MP_GT) {1837if((res = mp_copy(&t, &u)) != MP_OKAY)1838goto CLEANUP;18391840} else {1841if((res = mp_copy(&t, &v)) != MP_OKAY)1842goto CLEANUP;18431844/* v = -t */1845if(SIGN(&t) == ZPOS)1846SIGN(&v) = NEG;1847else1848SIGN(&v) = ZPOS;1849}18501851if((res = mp_sub(&u, &v, &t)) != MP_OKAY)1852goto CLEANUP;18531854if(s_mp_cmp_d(&t, 0) == MP_EQ)1855break;1856}18571858s_mp_2expt(&v, k); /* v = 2^k */1859res = mp_mul(&u, &v, c); /* c = u * v */18601861CLEANUP:1862mp_clear(&v);1863V:1864mp_clear(&u);1865U:1866mp_clear(&t);18671868return res;18691870} /* end mp_gcd() */18711872/* }}} */18731874/* {{{ mp_lcm(a, b, c) */18751876/* We compute the least common multiple using the rule:18771878ab = [a, b](a, b)18791880... by computing the product, and dividing out the gcd.1881*/18821883mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)1884{1885mp_int gcd, prod;1886mp_err res;18871888ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);18891890/* Set up temporaries */1891if((res = mp_init(&gcd, FLAG(a))) != MP_OKAY)1892return res;1893if((res = mp_init(&prod, FLAG(a))) != MP_OKAY)1894goto GCD;18951896if((res = mp_mul(a, b, &prod)) != MP_OKAY)1897goto CLEANUP;1898if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)1899goto CLEANUP;19001901res = mp_div(&prod, &gcd, c, NULL);19021903CLEANUP:1904mp_clear(&prod);1905GCD:1906mp_clear(&gcd);19071908return res;19091910} /* end mp_lcm() */19111912/* }}} */19131914/* {{{ mp_xgcd(a, b, g, x, y) */19151916/*1917mp_xgcd(a, b, g, x, y)19181919Compute g = (a, b) and values x and y satisfying Bezout's identity1920(that is, ax + by = g). This uses the binary extended GCD algorithm1921based on the Stein algorithm used for mp_gcd()1922See algorithm 14.61 in Handbook of Applied Cryptogrpahy.1923*/19241925mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y)1926{1927mp_int gx, xc, yc, u, v, A, B, C, D;1928mp_int *clean[9];1929mp_err res;1930int last = -1;19311932if(mp_cmp_z(b) == 0)1933return MP_RANGE;19341935/* Initialize all these variables we need */1936MP_CHECKOK( mp_init(&u, FLAG(a)) );1937clean[++last] = &u;1938MP_CHECKOK( mp_init(&v, FLAG(a)) );1939clean[++last] = &v;1940MP_CHECKOK( mp_init(&gx, FLAG(a)) );1941clean[++last] = &gx;1942MP_CHECKOK( mp_init(&A, FLAG(a)) );1943clean[++last] = &A;1944MP_CHECKOK( mp_init(&B, FLAG(a)) );1945clean[++last] = &B;1946MP_CHECKOK( mp_init(&C, FLAG(a)) );1947clean[++last] = &C;1948MP_CHECKOK( mp_init(&D, FLAG(a)) );1949clean[++last] = &D;1950MP_CHECKOK( mp_init_copy(&xc, a) );1951clean[++last] = &xc;1952mp_abs(&xc, &xc);1953MP_CHECKOK( mp_init_copy(&yc, b) );1954clean[++last] = &yc;1955mp_abs(&yc, &yc);19561957mp_set(&gx, 1);19581959/* Divide by two until at least one of them is odd */1960while(mp_iseven(&xc) && mp_iseven(&yc)) {1961mp_size nx = mp_trailing_zeros(&xc);1962mp_size ny = mp_trailing_zeros(&yc);1963mp_size n = MP_MIN(nx, ny);1964s_mp_div_2d(&xc,n);1965s_mp_div_2d(&yc,n);1966MP_CHECKOK( s_mp_mul_2d(&gx,n) );1967}19681969mp_copy(&xc, &u);1970mp_copy(&yc, &v);1971mp_set(&A, 1); mp_set(&D, 1);19721973/* Loop through binary GCD algorithm */1974do {1975while(mp_iseven(&u)) {1976s_mp_div_2(&u);19771978if(mp_iseven(&A) && mp_iseven(&B)) {1979s_mp_div_2(&A); s_mp_div_2(&B);1980} else {1981MP_CHECKOK( mp_add(&A, &yc, &A) );1982s_mp_div_2(&A);1983MP_CHECKOK( mp_sub(&B, &xc, &B) );1984s_mp_div_2(&B);1985}1986}19871988while(mp_iseven(&v)) {1989s_mp_div_2(&v);19901991if(mp_iseven(&C) && mp_iseven(&D)) {1992s_mp_div_2(&C); s_mp_div_2(&D);1993} else {1994MP_CHECKOK( mp_add(&C, &yc, &C) );1995s_mp_div_2(&C);1996MP_CHECKOK( mp_sub(&D, &xc, &D) );1997s_mp_div_2(&D);1998}1999}20002001if(mp_cmp(&u, &v) >= 0) {2002MP_CHECKOK( mp_sub(&u, &v, &u) );2003MP_CHECKOK( mp_sub(&A, &C, &A) );2004MP_CHECKOK( mp_sub(&B, &D, &B) );2005} else {2006MP_CHECKOK( mp_sub(&v, &u, &v) );2007MP_CHECKOK( mp_sub(&C, &A, &C) );2008MP_CHECKOK( mp_sub(&D, &B, &D) );2009}2010} while (mp_cmp_z(&u) != 0);20112012/* copy results to output */2013if(x)2014MP_CHECKOK( mp_copy(&C, x) );20152016if(y)2017MP_CHECKOK( mp_copy(&D, y) );20182019if(g)2020MP_CHECKOK( mp_mul(&gx, &v, g) );20212022CLEANUP:2023while(last >= 0)2024mp_clear(clean[last--]);20252026return res;20272028} /* end mp_xgcd() */20292030/* }}} */20312032mp_size mp_trailing_zeros(const mp_int *mp)2033{2034mp_digit d;2035mp_size n = 0;2036unsigned int ix;20372038if (!mp || !MP_DIGITS(mp) || !mp_cmp_z(mp))2039return n;20402041for (ix = 0; !(d = MP_DIGIT(mp,ix)) && (ix < MP_USED(mp)); ++ix)2042n += MP_DIGIT_BIT;2043if (!d)2044return 0; /* shouldn't happen, but ... */2045#if !defined(MP_USE_UINT_DIGIT)2046if (!(d & 0xffffffffU)) {2047d >>= 32;2048n += 32;2049}2050#endif2051if (!(d & 0xffffU)) {2052d >>= 16;2053n += 16;2054}2055if (!(d & 0xffU)) {2056d >>= 8;2057n += 8;2058}2059if (!(d & 0xfU)) {2060d >>= 4;2061n += 4;2062}2063if (!(d & 0x3U)) {2064d >>= 2;2065n += 2;2066}2067if (!(d & 0x1U)) {2068d >>= 1;2069n += 1;2070}2071#if MP_ARGCHK == 22072assert(0 != (d & 1));2073#endif2074return n;2075}20762077/* Given a and prime p, computes c and k such that a*c == 2**k (mod p).2078** Returns k (positive) or error (negative).2079** This technique from the paper "Fast Modular Reciprocals" (unpublished)2080** by Richard Schroeppel (a.k.a. Captain Nemo).2081*/2082mp_err s_mp_almost_inverse(const mp_int *a, const mp_int *p, mp_int *c)2083{2084mp_err res;2085mp_err k = 0;2086mp_int d, f, g;20872088ARGCHK(a && p && c, MP_BADARG);20892090MP_DIGITS(&d) = 0;2091MP_DIGITS(&f) = 0;2092MP_DIGITS(&g) = 0;2093MP_CHECKOK( mp_init(&d, FLAG(a)) );2094MP_CHECKOK( mp_init_copy(&f, a) ); /* f = a */2095MP_CHECKOK( mp_init_copy(&g, p) ); /* g = p */20962097mp_set(c, 1);2098mp_zero(&d);20992100if (mp_cmp_z(&f) == 0) {2101res = MP_UNDEF;2102} else2103for (;;) {2104int diff_sign;2105while (mp_iseven(&f)) {2106mp_size n = mp_trailing_zeros(&f);2107if (!n) {2108res = MP_UNDEF;2109goto CLEANUP;2110}2111s_mp_div_2d(&f, n);2112MP_CHECKOK( s_mp_mul_2d(&d, n) );2113k += n;2114}2115if (mp_cmp_d(&f, 1) == MP_EQ) { /* f == 1 */2116res = k;2117break;2118}2119diff_sign = mp_cmp(&f, &g);2120if (diff_sign < 0) { /* f < g */2121s_mp_exch(&f, &g);2122s_mp_exch(c, &d);2123} else if (diff_sign == 0) { /* f == g */2124res = MP_UNDEF; /* a and p are not relatively prime */2125break;2126}2127if ((MP_DIGIT(&f,0) % 4) == (MP_DIGIT(&g,0) % 4)) {2128MP_CHECKOK( mp_sub(&f, &g, &f) ); /* f = f - g */2129MP_CHECKOK( mp_sub(c, &d, c) ); /* c = c - d */2130} else {2131MP_CHECKOK( mp_add(&f, &g, &f) ); /* f = f + g */2132MP_CHECKOK( mp_add(c, &d, c) ); /* c = c + d */2133}2134}2135if (res >= 0) {2136if (s_mp_cmp(c, p) >= 0) {2137MP_CHECKOK( mp_div(c, p, NULL, c));2138}2139if (MP_SIGN(c) != MP_ZPOS) {2140MP_CHECKOK( mp_add(c, p, c) );2141}2142res = k;2143}21442145CLEANUP:2146mp_clear(&d);2147mp_clear(&f);2148mp_clear(&g);2149return res;2150}21512152/* Compute T = (P ** -1) mod MP_RADIX. Also works for 16-bit mp_digits.2153** This technique from the paper "Fast Modular Reciprocals" (unpublished)2154** by Richard Schroeppel (a.k.a. Captain Nemo).2155*/2156mp_digit s_mp_invmod_radix(mp_digit P)2157{2158mp_digit T = P;2159T *= 2 - (P * T);2160T *= 2 - (P * T);2161T *= 2 - (P * T);2162T *= 2 - (P * T);2163#if !defined(MP_USE_UINT_DIGIT)2164T *= 2 - (P * T);2165T *= 2 - (P * T);2166#endif2167return T;2168}21692170/* Given c, k, and prime p, where a*c == 2**k (mod p),2171** Compute x = (a ** -1) mod p. This is similar to Montgomery reduction.2172** This technique from the paper "Fast Modular Reciprocals" (unpublished)2173** by Richard Schroeppel (a.k.a. Captain Nemo).2174*/2175mp_err s_mp_fixup_reciprocal(const mp_int *c, const mp_int *p, int k, mp_int *x)2176{2177int k_orig = k;2178mp_digit r;2179mp_size ix;2180mp_err res;21812182if (mp_cmp_z(c) < 0) { /* c < 0 */2183MP_CHECKOK( mp_add(c, p, x) ); /* x = c + p */2184} else {2185MP_CHECKOK( mp_copy(c, x) ); /* x = c */2186}21872188/* make sure x is large enough */2189ix = MP_HOWMANY(k, MP_DIGIT_BIT) + MP_USED(p) + 1;2190ix = MP_MAX(ix, MP_USED(x));2191MP_CHECKOK( s_mp_pad(x, ix) );21922193r = 0 - s_mp_invmod_radix(MP_DIGIT(p,0));21942195for (ix = 0; k > 0; ix++) {2196int j = MP_MIN(k, MP_DIGIT_BIT);2197mp_digit v = r * MP_DIGIT(x, ix);2198if (j < MP_DIGIT_BIT) {2199v &= ((mp_digit)1 << j) - 1; /* v = v mod (2 ** j) */2200}2201s_mp_mul_d_add_offset(p, v, x, ix); /* x += p * v * (RADIX ** ix) */2202k -= j;2203}2204s_mp_clamp(x);2205s_mp_div_2d(x, k_orig);2206res = MP_OKAY;22072208CLEANUP:2209return res;2210}22112212/* compute mod inverse using Schroeppel's method, only if m is odd */2213mp_err s_mp_invmod_odd_m(const mp_int *a, const mp_int *m, mp_int *c)2214{2215int k;2216mp_err res;2217mp_int x;22182219ARGCHK(a && m && c, MP_BADARG);22202221if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)2222return MP_RANGE;2223if (mp_iseven(m))2224return MP_UNDEF;22252226MP_DIGITS(&x) = 0;22272228if (a == c) {2229if ((res = mp_init_copy(&x, a)) != MP_OKAY)2230return res;2231if (a == m)2232m = &x;2233a = &x;2234} else if (m == c) {2235if ((res = mp_init_copy(&x, m)) != MP_OKAY)2236return res;2237m = &x;2238} else {2239MP_DIGITS(&x) = 0;2240}22412242MP_CHECKOK( s_mp_almost_inverse(a, m, c) );2243k = res;2244MP_CHECKOK( s_mp_fixup_reciprocal(c, m, k, c) );2245CLEANUP:2246mp_clear(&x);2247return res;2248}22492250/* Known good algorithm for computing modular inverse. But slow. */2251mp_err mp_invmod_xgcd(const mp_int *a, const mp_int *m, mp_int *c)2252{2253mp_int g, x;2254mp_err res;22552256ARGCHK(a && m && c, MP_BADARG);22572258if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)2259return MP_RANGE;22602261MP_DIGITS(&g) = 0;2262MP_DIGITS(&x) = 0;2263MP_CHECKOK( mp_init(&x, FLAG(a)) );2264MP_CHECKOK( mp_init(&g, FLAG(a)) );22652266MP_CHECKOK( mp_xgcd(a, m, &g, &x, NULL) );22672268if (mp_cmp_d(&g, 1) != MP_EQ) {2269res = MP_UNDEF;2270goto CLEANUP;2271}22722273res = mp_mod(&x, m, c);2274SIGN(c) = SIGN(a);22752276CLEANUP:2277mp_clear(&x);2278mp_clear(&g);22792280return res;2281}22822283/* modular inverse where modulus is 2**k. */2284/* c = a**-1 mod 2**k */2285mp_err s_mp_invmod_2d(const mp_int *a, mp_size k, mp_int *c)2286{2287mp_err res;2288mp_size ix = k + 4;2289mp_int t0, t1, val, tmp, two2k;22902291static const mp_digit d2 = 2;2292static const mp_int two = { 0, MP_ZPOS, 1, 1, (mp_digit *)&d2 };22932294if (mp_iseven(a))2295return MP_UNDEF;2296if (k <= MP_DIGIT_BIT) {2297mp_digit i = s_mp_invmod_radix(MP_DIGIT(a,0));2298if (k < MP_DIGIT_BIT)2299i &= ((mp_digit)1 << k) - (mp_digit)1;2300mp_set(c, i);2301return MP_OKAY;2302}2303MP_DIGITS(&t0) = 0;2304MP_DIGITS(&t1) = 0;2305MP_DIGITS(&val) = 0;2306MP_DIGITS(&tmp) = 0;2307MP_DIGITS(&two2k) = 0;2308MP_CHECKOK( mp_init_copy(&val, a) );2309s_mp_mod_2d(&val, k);2310MP_CHECKOK( mp_init_copy(&t0, &val) );2311MP_CHECKOK( mp_init_copy(&t1, &t0) );2312MP_CHECKOK( mp_init(&tmp, FLAG(a)) );2313MP_CHECKOK( mp_init(&two2k, FLAG(a)) );2314MP_CHECKOK( s_mp_2expt(&two2k, k) );2315do {2316MP_CHECKOK( mp_mul(&val, &t1, &tmp) );2317MP_CHECKOK( mp_sub(&two, &tmp, &tmp) );2318MP_CHECKOK( mp_mul(&t1, &tmp, &t1) );2319s_mp_mod_2d(&t1, k);2320while (MP_SIGN(&t1) != MP_ZPOS) {2321MP_CHECKOK( mp_add(&t1, &two2k, &t1) );2322}2323if (mp_cmp(&t1, &t0) == MP_EQ)2324break;2325MP_CHECKOK( mp_copy(&t1, &t0) );2326} while (--ix > 0);2327if (!ix) {2328res = MP_UNDEF;2329} else {2330mp_exch(c, &t1);2331}23322333CLEANUP:2334mp_clear(&t0);2335mp_clear(&t1);2336mp_clear(&val);2337mp_clear(&tmp);2338mp_clear(&two2k);2339return res;2340}23412342mp_err s_mp_invmod_even_m(const mp_int *a, const mp_int *m, mp_int *c)2343{2344mp_err res;2345mp_size k;2346mp_int oddFactor, evenFactor; /* factors of the modulus */2347mp_int oddPart, evenPart; /* parts to combine via CRT. */2348mp_int C2, tmp1, tmp2;23492350/*static const mp_digit d1 = 1; */2351/*static const mp_int one = { MP_ZPOS, 1, 1, (mp_digit *)&d1 }; */23522353if ((res = s_mp_ispow2(m)) >= 0) {2354k = res;2355return s_mp_invmod_2d(a, k, c);2356}2357MP_DIGITS(&oddFactor) = 0;2358MP_DIGITS(&evenFactor) = 0;2359MP_DIGITS(&oddPart) = 0;2360MP_DIGITS(&evenPart) = 0;2361MP_DIGITS(&C2) = 0;2362MP_DIGITS(&tmp1) = 0;2363MP_DIGITS(&tmp2) = 0;23642365MP_CHECKOK( mp_init_copy(&oddFactor, m) ); /* oddFactor = m */2366MP_CHECKOK( mp_init(&evenFactor, FLAG(m)) );2367MP_CHECKOK( mp_init(&oddPart, FLAG(m)) );2368MP_CHECKOK( mp_init(&evenPart, FLAG(m)) );2369MP_CHECKOK( mp_init(&C2, FLAG(m)) );2370MP_CHECKOK( mp_init(&tmp1, FLAG(m)) );2371MP_CHECKOK( mp_init(&tmp2, FLAG(m)) );23722373k = mp_trailing_zeros(m);2374s_mp_div_2d(&oddFactor, k);2375MP_CHECKOK( s_mp_2expt(&evenFactor, k) );23762377/* compute a**-1 mod oddFactor. */2378MP_CHECKOK( s_mp_invmod_odd_m(a, &oddFactor, &oddPart) );2379/* compute a**-1 mod evenFactor, where evenFactor == 2**k. */2380MP_CHECKOK( s_mp_invmod_2d( a, k, &evenPart) );23812382/* Use Chinese Remainer theorem to compute a**-1 mod m. */2383/* let m1 = oddFactor, v1 = oddPart,2384* let m2 = evenFactor, v2 = evenPart.2385*/23862387/* Compute C2 = m1**-1 mod m2. */2388MP_CHECKOK( s_mp_invmod_2d(&oddFactor, k, &C2) );23892390/* compute u = (v2 - v1)*C2 mod m2 */2391MP_CHECKOK( mp_sub(&evenPart, &oddPart, &tmp1) );2392MP_CHECKOK( mp_mul(&tmp1, &C2, &tmp2) );2393s_mp_mod_2d(&tmp2, k);2394while (MP_SIGN(&tmp2) != MP_ZPOS) {2395MP_CHECKOK( mp_add(&tmp2, &evenFactor, &tmp2) );2396}23972398/* compute answer = v1 + u*m1 */2399MP_CHECKOK( mp_mul(&tmp2, &oddFactor, c) );2400MP_CHECKOK( mp_add(&oddPart, c, c) );2401/* not sure this is necessary, but it's low cost if not. */2402MP_CHECKOK( mp_mod(c, m, c) );24032404CLEANUP:2405mp_clear(&oddFactor);2406mp_clear(&evenFactor);2407mp_clear(&oddPart);2408mp_clear(&evenPart);2409mp_clear(&C2);2410mp_clear(&tmp1);2411mp_clear(&tmp2);2412return res;2413}241424152416/* {{{ mp_invmod(a, m, c) */24172418/*2419mp_invmod(a, m, c)24202421Compute c = a^-1 (mod m), if there is an inverse for a (mod m).2422This is equivalent to the question of whether (a, m) = 1. If not,2423MP_UNDEF is returned, and there is no inverse.2424*/24252426mp_err mp_invmod(const mp_int *a, const mp_int *m, mp_int *c)2427{24282429ARGCHK(a && m && c, MP_BADARG);24302431if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)2432return MP_RANGE;24332434if (mp_isodd(m)) {2435return s_mp_invmod_odd_m(a, m, c);2436}2437if (mp_iseven(a))2438return MP_UNDEF; /* not invertable */24392440return s_mp_invmod_even_m(a, m, c);24412442} /* end mp_invmod() */24432444/* }}} */2445#endif /* if MP_NUMTH */24462447/* }}} */24482449/*------------------------------------------------------------------------*/2450/* {{{ mp_print(mp, ofp) */24512452#if MP_IOFUNC2453/*2454mp_print(mp, ofp)24552456Print a textual representation of the given mp_int on the output2457stream 'ofp'. Output is generated using the internal radix.2458*/24592460void mp_print(mp_int *mp, FILE *ofp)2461{2462int ix;24632464if(mp == NULL || ofp == NULL)2465return;24662467fputc((SIGN(mp) == NEG) ? '-' : '+', ofp);24682469for(ix = USED(mp) - 1; ix >= 0; ix--) {2470fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));2471}24722473} /* end mp_print() */24742475#endif /* if MP_IOFUNC */24762477/* }}} */24782479/*------------------------------------------------------------------------*/2480/* {{{ More I/O Functions */24812482/* {{{ mp_read_raw(mp, str, len) */24832484/*2485mp_read_raw(mp, str, len)24862487Read in a raw value (base 256) into the given mp_int2488*/24892490mp_err mp_read_raw(mp_int *mp, char *str, int len)2491{2492int ix;2493mp_err res;2494unsigned char *ustr = (unsigned char *)str;24952496ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);24972498mp_zero(mp);24992500/* Get sign from first byte */2501if(ustr[0])2502SIGN(mp) = NEG;2503else2504SIGN(mp) = ZPOS;25052506/* Read the rest of the digits */2507for(ix = 1; ix < len; ix++) {2508if((res = mp_mul_d(mp, 256, mp)) != MP_OKAY)2509return res;2510if((res = mp_add_d(mp, ustr[ix], mp)) != MP_OKAY)2511return res;2512}25132514return MP_OKAY;25152516} /* end mp_read_raw() */25172518/* }}} */25192520/* {{{ mp_raw_size(mp) */25212522int mp_raw_size(mp_int *mp)2523{2524ARGCHK(mp != NULL, 0);25252526return (USED(mp) * sizeof(mp_digit)) + 1;25272528} /* end mp_raw_size() */25292530/* }}} */25312532/* {{{ mp_toraw(mp, str) */25332534mp_err mp_toraw(mp_int *mp, char *str)2535{2536int ix, jx, pos = 1;25372538ARGCHK(mp != NULL && str != NULL, MP_BADARG);25392540str[0] = (char)SIGN(mp);25412542/* Iterate over each digit... */2543for(ix = USED(mp) - 1; ix >= 0; ix--) {2544mp_digit d = DIGIT(mp, ix);25452546/* Unpack digit bytes, high order first */2547for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {2548str[pos++] = (char)(d >> (jx * CHAR_BIT));2549}2550}25512552return MP_OKAY;25532554} /* end mp_toraw() */25552556/* }}} */25572558/* {{{ mp_read_radix(mp, str, radix) */25592560/*2561mp_read_radix(mp, str, radix)25622563Read an integer from the given string, and set mp to the resulting2564value. The input is presumed to be in base 10. Leading non-digit2565characters are ignored, and the function reads until a non-digit2566character or the end of the string.2567*/25682569mp_err mp_read_radix(mp_int *mp, const char *str, int radix)2570{2571int ix = 0, val = 0;2572mp_err res;2573mp_sign sig = ZPOS;25742575ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX,2576MP_BADARG);25772578mp_zero(mp);25792580/* Skip leading non-digit characters until a digit or '-' or '+' */2581while(str[ix] &&2582(s_mp_tovalue(str[ix], radix) < 0) &&2583str[ix] != '-' &&2584str[ix] != '+') {2585++ix;2586}25872588if(str[ix] == '-') {2589sig = NEG;2590++ix;2591} else if(str[ix] == '+') {2592sig = ZPOS; /* this is the default anyway... */2593++ix;2594}25952596while((val = s_mp_tovalue(str[ix], radix)) >= 0) {2597if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)2598return res;2599if((res = s_mp_add_d(mp, val)) != MP_OKAY)2600return res;2601++ix;2602}26032604if(s_mp_cmp_d(mp, 0) == MP_EQ)2605SIGN(mp) = ZPOS;2606else2607SIGN(mp) = sig;26082609return MP_OKAY;26102611} /* end mp_read_radix() */26122613mp_err mp_read_variable_radix(mp_int *a, const char * str, int default_radix)2614{2615int radix = default_radix;2616int cx;2617mp_sign sig = ZPOS;2618mp_err res;26192620/* Skip leading non-digit characters until a digit or '-' or '+' */2621while ((cx = *str) != 0 &&2622(s_mp_tovalue(cx, radix) < 0) &&2623cx != '-' &&2624cx != '+') {2625++str;2626}26272628if (cx == '-') {2629sig = NEG;2630++str;2631} else if (cx == '+') {2632sig = ZPOS; /* this is the default anyway... */2633++str;2634}26352636if (str[0] == '0') {2637if ((str[1] | 0x20) == 'x') {2638radix = 16;2639str += 2;2640} else {2641radix = 8;2642str++;2643}2644}2645res = mp_read_radix(a, str, radix);2646if (res == MP_OKAY) {2647MP_SIGN(a) = (s_mp_cmp_d(a, 0) == MP_EQ) ? ZPOS : sig;2648}2649return res;2650}26512652/* }}} */26532654/* {{{ mp_radix_size(mp, radix) */26552656int mp_radix_size(mp_int *mp, int radix)2657{2658int bits;26592660if(!mp || radix < 2 || radix > MAX_RADIX)2661return 0;26622663bits = USED(mp) * DIGIT_BIT - 1;26642665return s_mp_outlen(bits, radix);26662667} /* end mp_radix_size() */26682669/* }}} */26702671/* {{{ mp_toradix(mp, str, radix) */26722673mp_err mp_toradix(mp_int *mp, char *str, int radix)2674{2675int ix, pos = 0;26762677ARGCHK(mp != NULL && str != NULL, MP_BADARG);2678ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);26792680if(mp_cmp_z(mp) == MP_EQ) {2681str[0] = '0';2682str[1] = '\0';2683} else {2684mp_err res;2685mp_int tmp;2686mp_sign sgn;2687mp_digit rem, rdx = (mp_digit)radix;2688char ch;26892690if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)2691return res;26922693/* Save sign for later, and take absolute value */2694sgn = SIGN(&tmp); SIGN(&tmp) = ZPOS;26952696/* Generate output digits in reverse order */2697while(mp_cmp_z(&tmp) != 0) {2698if((res = mp_div_d(&tmp, rdx, &tmp, &rem)) != MP_OKAY) {2699mp_clear(&tmp);2700return res;2701}27022703/* Generate digits, use capital letters */2704ch = s_mp_todigit(rem, radix, 0);27052706str[pos++] = ch;2707}27082709/* Add - sign if original value was negative */2710if(sgn == NEG)2711str[pos++] = '-';27122713/* Add trailing NUL to end the string */2714str[pos--] = '\0';27152716/* Reverse the digits and sign indicator */2717ix = 0;2718while(ix < pos) {2719char tmp = str[ix];27202721str[ix] = str[pos];2722str[pos] = tmp;2723++ix;2724--pos;2725}27262727mp_clear(&tmp);2728}27292730return MP_OKAY;27312732} /* end mp_toradix() */27332734/* }}} */27352736/* {{{ mp_tovalue(ch, r) */27372738int mp_tovalue(char ch, int r)2739{2740return s_mp_tovalue(ch, r);27412742} /* end mp_tovalue() */27432744/* }}} */27452746/* }}} */27472748/* {{{ mp_strerror(ec) */27492750/*2751mp_strerror(ec)27522753Return a string describing the meaning of error code 'ec'. The2754string returned is allocated in static memory, so the caller should2755not attempt to modify or free the memory associated with this2756string.2757*/2758const char *mp_strerror(mp_err ec)2759{2760int aec = (ec < 0) ? -ec : ec;27612762/* Code values are negative, so the senses of these comparisons2763are accurate */2764if(ec < MP_LAST_CODE || ec > MP_OKAY) {2765return mp_err_string[0]; /* unknown error code */2766} else {2767return mp_err_string[aec + 1];2768}27692770} /* end mp_strerror() */27712772/* }}} */27732774/*========================================================================*/2775/*------------------------------------------------------------------------*/2776/* Static function definitions (internal use only) */27772778/* {{{ Memory management */27792780/* {{{ s_mp_grow(mp, min) */27812782/* Make sure there are at least 'min' digits allocated to mp */2783mp_err s_mp_grow(mp_int *mp, mp_size min)2784{2785if(min > ALLOC(mp)) {2786mp_digit *tmp;27872788/* Set min to next nearest default precision block size */2789min = MP_ROUNDUP(min, s_mp_defprec);27902791if((tmp = s_mp_alloc(min, sizeof(mp_digit), FLAG(mp))) == NULL)2792return MP_MEM;27932794s_mp_copy(DIGITS(mp), tmp, USED(mp));27952796#if MP_CRYPTO2797s_mp_setz(DIGITS(mp), ALLOC(mp));2798#endif2799s_mp_free(DIGITS(mp), ALLOC(mp));2800DIGITS(mp) = tmp;2801ALLOC(mp) = min;2802}28032804return MP_OKAY;28052806} /* end s_mp_grow() */28072808/* }}} */28092810/* {{{ s_mp_pad(mp, min) */28112812/* Make sure the used size of mp is at least 'min', growing if needed */2813mp_err s_mp_pad(mp_int *mp, mp_size min)2814{2815if(min > USED(mp)) {2816mp_err res;28172818/* Make sure there is room to increase precision */2819if (min > ALLOC(mp)) {2820if ((res = s_mp_grow(mp, min)) != MP_OKAY)2821return res;2822} else {2823s_mp_setz(DIGITS(mp) + USED(mp), min - USED(mp));2824}28252826/* Increase precision; should already be 0-filled */2827USED(mp) = min;2828}28292830return MP_OKAY;28312832} /* end s_mp_pad() */28332834/* }}} */28352836/* {{{ s_mp_setz(dp, count) */28372838#if MP_MACRO == 02839/* Set 'count' digits pointed to by dp to be zeroes */2840void s_mp_setz(mp_digit *dp, mp_size count)2841{2842#if MP_MEMSET == 02843int ix;28442845for(ix = 0; ix < count; ix++)2846dp[ix] = 0;2847#else2848memset(dp, 0, count * sizeof(mp_digit));2849#endif28502851} /* end s_mp_setz() */2852#endif28532854/* }}} */28552856/* {{{ s_mp_copy(sp, dp, count) */28572858#if MP_MACRO == 02859/* Copy 'count' digits from sp to dp */2860void s_mp_copy(const mp_digit *sp, mp_digit *dp, mp_size count)2861{2862#if MP_MEMCPY == 02863int ix;28642865for(ix = 0; ix < count; ix++)2866dp[ix] = sp[ix];2867#else2868memcpy(dp, sp, count * sizeof(mp_digit));2869#endif28702871} /* end s_mp_copy() */2872#endif28732874/* }}} */28752876/* {{{ s_mp_alloc(nb, ni, kmflag) */28772878#if MP_MACRO == 02879/* Allocate ni records of nb bytes each, and return a pointer to that */2880void *s_mp_alloc(size_t nb, size_t ni, int kmflag)2881{2882++mp_allocs;2883#ifdef _KERNEL2884mp_int *mp;2885mp = kmem_zalloc(nb * ni, kmflag);2886if (mp != NULL)2887FLAG(mp) = kmflag;2888return (mp);2889#else2890return calloc(nb, ni);2891#endif28922893} /* end s_mp_alloc() */2894#endif28952896/* }}} */28972898/* {{{ s_mp_free(ptr) */28992900#if MP_MACRO == 02901/* Free the memory pointed to by ptr */2902void s_mp_free(void *ptr, mp_size alloc)2903{2904if(ptr) {2905++mp_frees;2906#ifdef _KERNEL2907kmem_free(ptr, alloc * sizeof (mp_digit));2908#else2909free(ptr);2910#endif2911}2912} /* end s_mp_free() */2913#endif29142915/* }}} */29162917/* {{{ s_mp_clamp(mp) */29182919#if MP_MACRO == 02920/* Remove leading zeroes from the given value */2921void s_mp_clamp(mp_int *mp)2922{2923mp_size used = MP_USED(mp);2924while (used > 1 && DIGIT(mp, used - 1) == 0)2925--used;2926MP_USED(mp) = used;2927} /* end s_mp_clamp() */2928#endif29292930/* }}} */29312932/* {{{ s_mp_exch(a, b) */29332934/* Exchange the data for a and b; (b, a) = (a, b) */2935void s_mp_exch(mp_int *a, mp_int *b)2936{2937mp_int tmp;29382939tmp = *a;2940*a = *b;2941*b = tmp;29422943} /* end s_mp_exch() */29442945/* }}} */29462947/* }}} */29482949/* {{{ Arithmetic helpers */29502951/* {{{ s_mp_lshd(mp, p) */29522953/*2954Shift mp leftward by p digits, growing if needed, and zero-filling2955the in-shifted digits at the right end. This is a convenient2956alternative to multiplication by powers of the radix2957The value of USED(mp) must already have been set to the value for2958the shifted result.2959*/29602961mp_err s_mp_lshd(mp_int *mp, mp_size p)2962{2963mp_err res;2964mp_size pos;2965int ix;29662967if(p == 0)2968return MP_OKAY;29692970if (MP_USED(mp) == 1 && MP_DIGIT(mp, 0) == 0)2971return MP_OKAY;29722973if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)2974return res;29752976pos = USED(mp) - 1;29772978/* Shift all the significant figures over as needed */2979for(ix = pos - p; ix >= 0; ix--)2980DIGIT(mp, ix + p) = DIGIT(mp, ix);29812982/* Fill the bottom digits with zeroes */2983for(ix = 0; ix < p; ix++)2984DIGIT(mp, ix) = 0;29852986return MP_OKAY;29872988} /* end s_mp_lshd() */29892990/* }}} */29912992/* {{{ s_mp_mul_2d(mp, d) */29932994/*2995Multiply the integer by 2^d, where d is a number of bits. This2996amounts to a bitwise shift of the value.2997*/2998mp_err s_mp_mul_2d(mp_int *mp, mp_digit d)2999{3000mp_err res;3001mp_digit dshift, bshift;3002mp_digit mask;30033004ARGCHK(mp != NULL, MP_BADARG);30053006dshift = d / MP_DIGIT_BIT;3007bshift = d % MP_DIGIT_BIT;3008/* bits to be shifted out of the top word */3009mask = ((mp_digit)~0 << (MP_DIGIT_BIT - bshift));3010mask &= MP_DIGIT(mp, MP_USED(mp) - 1);30113012if (MP_OKAY != (res = s_mp_pad(mp, MP_USED(mp) + dshift + (mask != 0) )))3013return res;30143015if (dshift && MP_OKAY != (res = s_mp_lshd(mp, dshift)))3016return res;30173018if (bshift) {3019mp_digit *pa = MP_DIGITS(mp);3020mp_digit *alim = pa + MP_USED(mp);3021mp_digit prev = 0;30223023for (pa += dshift; pa < alim; ) {3024mp_digit x = *pa;3025*pa++ = (x << bshift) | prev;3026prev = x >> (DIGIT_BIT - bshift);3027}3028}30293030s_mp_clamp(mp);3031return MP_OKAY;3032} /* end s_mp_mul_2d() */30333034/* {{{ s_mp_rshd(mp, p) */30353036/*3037Shift mp rightward by p digits. Maintains the invariant that3038digits above the precision are all zero. Digits shifted off the3039end are lost. Cannot fail.3040*/30413042void s_mp_rshd(mp_int *mp, mp_size p)3043{3044mp_size ix;3045mp_digit *src, *dst;30463047if(p == 0)3048return;30493050/* Shortcut when all digits are to be shifted off */3051if(p >= USED(mp)) {3052s_mp_setz(DIGITS(mp), ALLOC(mp));3053USED(mp) = 1;3054SIGN(mp) = ZPOS;3055return;3056}30573058/* Shift all the significant figures over as needed */3059dst = MP_DIGITS(mp);3060src = dst + p;3061for (ix = USED(mp) - p; ix > 0; ix--)3062*dst++ = *src++;30633064MP_USED(mp) -= p;3065/* Fill the top digits with zeroes */3066while (p-- > 0)3067*dst++ = 0;30683069#if 03070/* Strip off any leading zeroes */3071s_mp_clamp(mp);3072#endif30733074} /* end s_mp_rshd() */30753076/* }}} */30773078/* {{{ s_mp_div_2(mp) */30793080/* Divide by two -- take advantage of radix properties to do it fast */3081void s_mp_div_2(mp_int *mp)3082{3083s_mp_div_2d(mp, 1);30843085} /* end s_mp_div_2() */30863087/* }}} */30883089/* {{{ s_mp_mul_2(mp) */30903091mp_err s_mp_mul_2(mp_int *mp)3092{3093mp_digit *pd;3094unsigned int ix, used;3095mp_digit kin = 0;30963097/* Shift digits leftward by 1 bit */3098used = MP_USED(mp);3099pd = MP_DIGITS(mp);3100for (ix = 0; ix < used; ix++) {3101mp_digit d = *pd;3102*pd++ = (d << 1) | kin;3103kin = (d >> (DIGIT_BIT - 1));3104}31053106/* Deal with rollover from last digit */3107if (kin) {3108if (ix >= ALLOC(mp)) {3109mp_err res;3110if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)3111return res;3112}31133114DIGIT(mp, ix) = kin;3115USED(mp) += 1;3116}31173118return MP_OKAY;31193120} /* end s_mp_mul_2() */31213122/* }}} */31233124/* {{{ s_mp_mod_2d(mp, d) */31253126/*3127Remainder the integer by 2^d, where d is a number of bits. This3128amounts to a bitwise AND of the value, and does not require the full3129division code3130*/3131void s_mp_mod_2d(mp_int *mp, mp_digit d)3132{3133mp_size ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);3134mp_size ix;3135mp_digit dmask;31363137if(ndig >= USED(mp))3138return;31393140/* Flush all the bits above 2^d in its digit */3141dmask = ((mp_digit)1 << nbit) - 1;3142DIGIT(mp, ndig) &= dmask;31433144/* Flush all digits above the one with 2^d in it */3145for(ix = ndig + 1; ix < USED(mp); ix++)3146DIGIT(mp, ix) = 0;31473148s_mp_clamp(mp);31493150} /* end s_mp_mod_2d() */31513152/* }}} */31533154/* {{{ s_mp_div_2d(mp, d) */31553156/*3157Divide the integer by 2^d, where d is a number of bits. This3158amounts to a bitwise shift of the value, and does not require the3159full division code (used in Barrett reduction, see below)3160*/3161void s_mp_div_2d(mp_int *mp, mp_digit d)3162{3163int ix;3164mp_digit save, next, mask;31653166s_mp_rshd(mp, d / DIGIT_BIT);3167d %= DIGIT_BIT;3168if (d) {3169mask = ((mp_digit)1 << d) - 1;3170save = 0;3171for(ix = USED(mp) - 1; ix >= 0; ix--) {3172next = DIGIT(mp, ix) & mask;3173DIGIT(mp, ix) = (DIGIT(mp, ix) >> d) | (save << (DIGIT_BIT - d));3174save = next;3175}3176}3177s_mp_clamp(mp);31783179} /* end s_mp_div_2d() */31803181/* }}} */31823183/* {{{ s_mp_norm(a, b, *d) */31843185/*3186s_mp_norm(a, b, *d)31873188Normalize a and b for division, where b is the divisor. In order3189that we might make good guesses for quotient digits, we want the3190leading digit of b to be at least half the radix, which we3191accomplish by multiplying a and b by a power of 2. The exponent3192(shift count) is placed in *pd, so that the remainder can be shifted3193back at the end of the division process.3194*/31953196mp_err s_mp_norm(mp_int *a, mp_int *b, mp_digit *pd)3197{3198mp_digit d;3199mp_digit mask;3200mp_digit b_msd;3201mp_err res = MP_OKAY;32023203d = 0;3204mask = DIGIT_MAX & ~(DIGIT_MAX >> 1); /* mask is msb of digit */3205b_msd = DIGIT(b, USED(b) - 1);3206while (!(b_msd & mask)) {3207b_msd <<= 1;3208++d;3209}32103211if (d) {3212MP_CHECKOK( s_mp_mul_2d(a, d) );3213MP_CHECKOK( s_mp_mul_2d(b, d) );3214}32153216*pd = d;3217CLEANUP:3218return res;32193220} /* end s_mp_norm() */32213222/* }}} */32233224/* }}} */32253226/* {{{ Primitive digit arithmetic */32273228/* {{{ s_mp_add_d(mp, d) */32293230/* Add d to |mp| in place */3231mp_err s_mp_add_d(mp_int *mp, mp_digit d) /* unsigned digit addition */3232{3233#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3234mp_word w, k = 0;3235mp_size ix = 1;32363237w = (mp_word)DIGIT(mp, 0) + d;3238DIGIT(mp, 0) = ACCUM(w);3239k = CARRYOUT(w);32403241while(ix < USED(mp) && k) {3242w = (mp_word)DIGIT(mp, ix) + k;3243DIGIT(mp, ix) = ACCUM(w);3244k = CARRYOUT(w);3245++ix;3246}32473248if(k != 0) {3249mp_err res;32503251if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)3252return res;32533254DIGIT(mp, ix) = (mp_digit)k;3255}32563257return MP_OKAY;3258#else3259mp_digit * pmp = MP_DIGITS(mp);3260mp_digit sum, mp_i, carry = 0;3261mp_err res = MP_OKAY;3262int used = (int)MP_USED(mp);32633264mp_i = *pmp;3265*pmp++ = sum = d + mp_i;3266carry = (sum < d);3267while (carry && --used > 0) {3268mp_i = *pmp;3269*pmp++ = sum = carry + mp_i;3270carry = !sum;3271}3272if (carry && !used) {3273/* mp is growing */3274used = MP_USED(mp);3275MP_CHECKOK( s_mp_pad(mp, used + 1) );3276MP_DIGIT(mp, used) = carry;3277}3278CLEANUP:3279return res;3280#endif3281} /* end s_mp_add_d() */32823283/* }}} */32843285/* {{{ s_mp_sub_d(mp, d) */32863287/* Subtract d from |mp| in place, assumes |mp| > d */3288mp_err s_mp_sub_d(mp_int *mp, mp_digit d) /* unsigned digit subtract */3289{3290#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)3291mp_word w, b = 0;3292mp_size ix = 1;32933294/* Compute initial subtraction */3295w = (RADIX + (mp_word)DIGIT(mp, 0)) - d;3296b = CARRYOUT(w) ? 0 : 1;3297DIGIT(mp, 0) = ACCUM(w);32983299/* Propagate borrows leftward */3300while(b && ix < USED(mp)) {3301w = (RADIX + (mp_word)DIGIT(mp, ix)) - b;3302b = CARRYOUT(w) ? 0 : 1;3303DIGIT(mp, ix) = ACCUM(w);3304++ix;3305}33063307/* Remove leading zeroes */3308s_mp_clamp(mp);33093310/* If we have a borrow out, it's a violation of the input invariant */3311if(b)3312return MP_RANGE;3313else3314return MP_OKAY;3315#else3316mp_digit *pmp = MP_DIGITS(mp);3317mp_digit mp_i, diff, borrow;3318mp_size used = MP_USED(mp);33193320mp_i = *pmp;3321*pmp++ = diff = mp_i - d;3322borrow = (diff > mp_i);3323while (borrow && --used) {3324mp_i = *pmp;3325*pmp++ = diff = mp_i - borrow;3326borrow = (diff > mp_i);3327}3328s_mp_clamp(mp);3329return (borrow && !used) ? MP_RANGE : MP_OKAY;3330#endif3331} /* end s_mp_sub_d() */33323333/* }}} */33343335/* {{{ s_mp_mul_d(a, d) */33363337/* Compute a = a * d, single digit multiplication */3338mp_err s_mp_mul_d(mp_int *a, mp_digit d)3339{3340mp_err res;3341mp_size used;3342int pow;33433344if (!d) {3345mp_zero(a);3346return MP_OKAY;3347}3348if (d == 1)3349return MP_OKAY;3350if (0 <= (pow = s_mp_ispow2d(d))) {3351return s_mp_mul_2d(a, (mp_digit)pow);3352}33533354used = MP_USED(a);3355MP_CHECKOK( s_mp_pad(a, used + 1) );33563357s_mpv_mul_d(MP_DIGITS(a), used, d, MP_DIGITS(a));33583359s_mp_clamp(a);33603361CLEANUP:3362return res;33633364} /* end s_mp_mul_d() */33653366/* }}} */33673368/* {{{ s_mp_div_d(mp, d, r) */33693370/*3371s_mp_div_d(mp, d, r)33723373Compute the quotient mp = mp / d and remainder r = mp mod d, for a3374single digit d. If r is null, the remainder will be discarded.3375*/33763377mp_err s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)3378{3379#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)3380mp_word w = 0, q;3381#else3382mp_digit w = 0, q;3383#endif3384int ix;3385mp_err res;3386mp_int quot;3387mp_int rem;33883389if(d == 0)3390return MP_RANGE;3391if (d == 1) {3392if (r)3393*r = 0;3394return MP_OKAY;3395}3396/* could check for power of 2 here, but mp_div_d does that. */3397if (MP_USED(mp) == 1) {3398mp_digit n = MP_DIGIT(mp,0);3399mp_digit rem;34003401q = n / d;3402rem = n % d;3403MP_DIGIT(mp,0) = q;3404if (r)3405*r = rem;3406return MP_OKAY;3407}34083409MP_DIGITS(&rem) = 0;3410MP_DIGITS(") = 0;3411/* Make room for the quotient */3412MP_CHECKOK( mp_init_size(", USED(mp), FLAG(mp)) );34133414#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)3415for(ix = USED(mp) - 1; ix >= 0; ix--) {3416w = (w << DIGIT_BIT) | DIGIT(mp, ix);34173418if(w >= d) {3419q = w / d;3420w = w % d;3421} else {3422q = 0;3423}34243425s_mp_lshd(", 1);3426DIGIT(", 0) = (mp_digit)q;3427}3428#else3429{3430mp_digit p;3431#if !defined(MP_ASSEMBLY_DIV_2DX1D)3432mp_digit norm;3433#endif34343435MP_CHECKOK( mp_init_copy(&rem, mp) );34363437#if !defined(MP_ASSEMBLY_DIV_2DX1D)3438MP_DIGIT(", 0) = d;3439MP_CHECKOK( s_mp_norm(&rem, ", &norm) );3440if (norm)3441d <<= norm;3442MP_DIGIT(", 0) = 0;3443#endif34443445p = 0;3446for (ix = USED(&rem) - 1; ix >= 0; ix--) {3447w = DIGIT(&rem, ix);34483449if (p) {3450MP_CHECKOK( s_mpv_div_2dx1d(p, w, d, &q, &w) );3451} else if (w >= d) {3452q = w / d;3453w = w % d;3454} else {3455q = 0;3456}34573458MP_CHECKOK( s_mp_lshd(", 1) );3459DIGIT(", 0) = q;3460p = w;3461}3462#if !defined(MP_ASSEMBLY_DIV_2DX1D)3463if (norm)3464w >>= norm;3465#endif3466}3467#endif34683469/* Deliver the remainder, if desired */3470if(r)3471*r = (mp_digit)w;34723473s_mp_clamp(");3474mp_exch(", mp);3475CLEANUP:3476mp_clear(");3477mp_clear(&rem);34783479return res;3480} /* end s_mp_div_d() */34813482/* }}} */348334843485/* }}} */34863487/* {{{ Primitive full arithmetic */34883489/* {{{ s_mp_add(a, b) */34903491/* Compute a = |a| + |b| */3492mp_err s_mp_add(mp_int *a, const mp_int *b) /* magnitude addition */3493{3494#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3495mp_word w = 0;3496#else3497mp_digit d, sum, carry = 0;3498#endif3499mp_digit *pa, *pb;3500mp_size ix;3501mp_size used;3502mp_err res;35033504/* Make sure a has enough precision for the output value */3505if((USED(b) > USED(a)) && (res = s_mp_pad(a, USED(b))) != MP_OKAY)3506return res;35073508/*3509Add up all digits up to the precision of b. If b had initially3510the same precision as a, or greater, we took care of it by the3511padding step above, so there is no problem. If b had initially3512less precision, we'll have to make sure the carry out is duly3513propagated upward among the higher-order digits of the sum.3514*/3515pa = MP_DIGITS(a);3516pb = MP_DIGITS(b);3517used = MP_USED(b);3518for(ix = 0; ix < used; ix++) {3519#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3520w = w + *pa + *pb++;3521*pa++ = ACCUM(w);3522w = CARRYOUT(w);3523#else3524d = *pa;3525sum = d + *pb++;3526d = (sum < d); /* detect overflow */3527*pa++ = sum += carry;3528carry = d + (sum < carry); /* detect overflow */3529#endif3530}35313532/* If we run out of 'b' digits before we're actually done, make3533sure the carries get propagated upward...3534*/3535used = MP_USED(a);3536#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3537while (w && ix < used) {3538w = w + *pa;3539*pa++ = ACCUM(w);3540w = CARRYOUT(w);3541++ix;3542}3543#else3544while (carry && ix < used) {3545sum = carry + *pa;3546*pa++ = sum;3547carry = !sum;3548++ix;3549}3550#endif35513552/* If there's an overall carry out, increase precision and include3553it. We could have done this initially, but why touch the memory3554allocator unless we're sure we have to?3555*/3556#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3557if (w) {3558if((res = s_mp_pad(a, used + 1)) != MP_OKAY)3559return res;35603561DIGIT(a, ix) = (mp_digit)w;3562}3563#else3564if (carry) {3565if((res = s_mp_pad(a, used + 1)) != MP_OKAY)3566return res;35673568DIGIT(a, used) = carry;3569}3570#endif35713572return MP_OKAY;3573} /* end s_mp_add() */35743575/* }}} */35763577/* Compute c = |a| + |b| */ /* magnitude addition */3578mp_err s_mp_add_3arg(const mp_int *a, const mp_int *b, mp_int *c)3579{3580mp_digit *pa, *pb, *pc;3581#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3582mp_word w = 0;3583#else3584mp_digit sum, carry = 0, d;3585#endif3586mp_size ix;3587mp_size used;3588mp_err res;35893590MP_SIGN(c) = MP_SIGN(a);3591if (MP_USED(a) < MP_USED(b)) {3592const mp_int *xch = a;3593a = b;3594b = xch;3595}35963597/* Make sure a has enough precision for the output value */3598if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))3599return res;36003601/*3602Add up all digits up to the precision of b. If b had initially3603the same precision as a, or greater, we took care of it by the3604exchange step above, so there is no problem. If b had initially3605less precision, we'll have to make sure the carry out is duly3606propagated upward among the higher-order digits of the sum.3607*/3608pa = MP_DIGITS(a);3609pb = MP_DIGITS(b);3610pc = MP_DIGITS(c);3611used = MP_USED(b);3612for (ix = 0; ix < used; ix++) {3613#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3614w = w + *pa++ + *pb++;3615*pc++ = ACCUM(w);3616w = CARRYOUT(w);3617#else3618d = *pa++;3619sum = d + *pb++;3620d = (sum < d); /* detect overflow */3621*pc++ = sum += carry;3622carry = d + (sum < carry); /* detect overflow */3623#endif3624}36253626/* If we run out of 'b' digits before we're actually done, make3627sure the carries get propagated upward...3628*/3629for (used = MP_USED(a); ix < used; ++ix) {3630#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3631w = w + *pa++;3632*pc++ = ACCUM(w);3633w = CARRYOUT(w);3634#else3635*pc++ = sum = carry + *pa++;3636carry = (sum < carry);3637#endif3638}36393640/* If there's an overall carry out, increase precision and include3641it. We could have done this initially, but why touch the memory3642allocator unless we're sure we have to?3643*/3644#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3645if (w) {3646if((res = s_mp_pad(c, used + 1)) != MP_OKAY)3647return res;36483649DIGIT(c, used) = (mp_digit)w;3650++used;3651}3652#else3653if (carry) {3654if((res = s_mp_pad(c, used + 1)) != MP_OKAY)3655return res;36563657DIGIT(c, used) = carry;3658++used;3659}3660#endif3661MP_USED(c) = used;3662return MP_OKAY;3663}3664/* {{{ s_mp_add_offset(a, b, offset) */36653666/* Compute a = |a| + ( |b| * (RADIX ** offset) ) */3667mp_err s_mp_add_offset(mp_int *a, mp_int *b, mp_size offset)3668{3669#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3670mp_word w, k = 0;3671#else3672mp_digit d, sum, carry = 0;3673#endif3674mp_size ib;3675mp_size ia;3676mp_size lim;3677mp_err res;36783679/* Make sure a has enough precision for the output value */3680lim = MP_USED(b) + offset;3681if((lim > USED(a)) && (res = s_mp_pad(a, lim)) != MP_OKAY)3682return res;36833684/*3685Add up all digits up to the precision of b. If b had initially3686the same precision as a, or greater, we took care of it by the3687padding step above, so there is no problem. If b had initially3688less precision, we'll have to make sure the carry out is duly3689propagated upward among the higher-order digits of the sum.3690*/3691lim = USED(b);3692for(ib = 0, ia = offset; ib < lim; ib++, ia++) {3693#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3694w = (mp_word)DIGIT(a, ia) + DIGIT(b, ib) + k;3695DIGIT(a, ia) = ACCUM(w);3696k = CARRYOUT(w);3697#else3698d = MP_DIGIT(a, ia);3699sum = d + MP_DIGIT(b, ib);3700d = (sum < d);3701MP_DIGIT(a,ia) = sum += carry;3702carry = d + (sum < carry);3703#endif3704}37053706/* If we run out of 'b' digits before we're actually done, make3707sure the carries get propagated upward...3708*/3709#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3710for (lim = MP_USED(a); k && (ia < lim); ++ia) {3711w = (mp_word)DIGIT(a, ia) + k;3712DIGIT(a, ia) = ACCUM(w);3713k = CARRYOUT(w);3714}3715#else3716for (lim = MP_USED(a); carry && (ia < lim); ++ia) {3717d = MP_DIGIT(a, ia);3718MP_DIGIT(a,ia) = sum = d + carry;3719carry = (sum < d);3720}3721#endif37223723/* If there's an overall carry out, increase precision and include3724it. We could have done this initially, but why touch the memory3725allocator unless we're sure we have to?3726*/3727#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_ADD_WORD)3728if(k) {3729if((res = s_mp_pad(a, USED(a) + 1)) != MP_OKAY)3730return res;37313732DIGIT(a, ia) = (mp_digit)k;3733}3734#else3735if (carry) {3736if((res = s_mp_pad(a, lim + 1)) != MP_OKAY)3737return res;37383739DIGIT(a, lim) = carry;3740}3741#endif3742s_mp_clamp(a);37433744return MP_OKAY;37453746} /* end s_mp_add_offset() */37473748/* }}} */37493750/* {{{ s_mp_sub(a, b) */37513752/* Compute a = |a| - |b|, assumes |a| >= |b| */3753mp_err s_mp_sub(mp_int *a, const mp_int *b) /* magnitude subtract */3754{3755mp_digit *pa, *pb, *limit;3756#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)3757mp_sword w = 0;3758#else3759mp_digit d, diff, borrow = 0;3760#endif37613762/*3763Subtract and propagate borrow. Up to the precision of b, this3764accounts for the digits of b; after that, we just make sure the3765carries get to the right place. This saves having to pad b out to3766the precision of a just to make the loops work right...3767*/3768pa = MP_DIGITS(a);3769pb = MP_DIGITS(b);3770limit = pb + MP_USED(b);3771while (pb < limit) {3772#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)3773w = w + *pa - *pb++;3774*pa++ = ACCUM(w);3775w >>= MP_DIGIT_BIT;3776#else3777d = *pa;3778diff = d - *pb++;3779d = (diff > d); /* detect borrow */3780if (borrow && --diff == MP_DIGIT_MAX)3781++d;3782*pa++ = diff;3783borrow = d;3784#endif3785}3786limit = MP_DIGITS(a) + MP_USED(a);3787#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)3788while (w && pa < limit) {3789w = w + *pa;3790*pa++ = ACCUM(w);3791w >>= MP_DIGIT_BIT;3792}3793#else3794while (borrow && pa < limit) {3795d = *pa;3796*pa++ = diff = d - borrow;3797borrow = (diff > d);3798}3799#endif38003801/* Clobber any leading zeroes we created */3802s_mp_clamp(a);38033804/*3805If there was a borrow out, then |b| > |a| in violation3806of our input invariant. We've already done the work,3807but we'll at least complain about it...3808*/3809#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)3810return w ? MP_RANGE : MP_OKAY;3811#else3812return borrow ? MP_RANGE : MP_OKAY;3813#endif3814} /* end s_mp_sub() */38153816/* }}} */38173818/* Compute c = |a| - |b|, assumes |a| >= |b| */ /* magnitude subtract */3819mp_err s_mp_sub_3arg(const mp_int *a, const mp_int *b, mp_int *c)3820{3821mp_digit *pa, *pb, *pc;3822#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)3823mp_sword w = 0;3824#else3825mp_digit d, diff, borrow = 0;3826#endif3827int ix, limit;3828mp_err res;38293830MP_SIGN(c) = MP_SIGN(a);38313832/* Make sure a has enough precision for the output value */3833if (MP_OKAY != (res = s_mp_pad(c, MP_USED(a))))3834return res;38353836/*3837Subtract and propagate borrow. Up to the precision of b, this3838accounts for the digits of b; after that, we just make sure the3839carries get to the right place. This saves having to pad b out to3840the precision of a just to make the loops work right...3841*/3842pa = MP_DIGITS(a);3843pb = MP_DIGITS(b);3844pc = MP_DIGITS(c);3845limit = MP_USED(b);3846for (ix = 0; ix < limit; ++ix) {3847#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)3848w = w + *pa++ - *pb++;3849*pc++ = ACCUM(w);3850w >>= MP_DIGIT_BIT;3851#else3852d = *pa++;3853diff = d - *pb++;3854d = (diff > d);3855if (borrow && --diff == MP_DIGIT_MAX)3856++d;3857*pc++ = diff;3858borrow = d;3859#endif3860}3861for (limit = MP_USED(a); ix < limit; ++ix) {3862#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)3863w = w + *pa++;3864*pc++ = ACCUM(w);3865w >>= MP_DIGIT_BIT;3866#else3867d = *pa++;3868*pc++ = diff = d - borrow;3869borrow = (diff > d);3870#endif3871}38723873/* Clobber any leading zeroes we created */3874MP_USED(c) = ix;3875s_mp_clamp(c);38763877/*3878If there was a borrow out, then |b| > |a| in violation3879of our input invariant. We've already done the work,3880but we'll at least complain about it...3881*/3882#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_SUB_WORD)3883return w ? MP_RANGE : MP_OKAY;3884#else3885return borrow ? MP_RANGE : MP_OKAY;3886#endif3887}3888/* {{{ s_mp_mul(a, b) */38893890/* Compute a = |a| * |b| */3891mp_err s_mp_mul(mp_int *a, const mp_int *b)3892{3893return mp_mul(a, b, a);3894} /* end s_mp_mul() */38953896/* }}} */38973898#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)3899/* This trick works on Sparc V8 CPUs with the Workshop compilers. */3900#define MP_MUL_DxD(a, b, Phi, Plo) \3901{ unsigned long long product = (unsigned long long)a * b; \3902Plo = (mp_digit)product; \3903Phi = (mp_digit)(product >> MP_DIGIT_BIT); }3904#elif defined(OSF1)3905#define MP_MUL_DxD(a, b, Phi, Plo) \3906{ Plo = asm ("mulq %a0, %a1, %v0", a, b);\3907Phi = asm ("umulh %a0, %a1, %v0", a, b); }3908#else3909#define MP_MUL_DxD(a, b, Phi, Plo) \3910{ mp_digit a0b1, a1b0; \3911Plo = (a & MP_HALF_DIGIT_MAX) * (b & MP_HALF_DIGIT_MAX); \3912Phi = (a >> MP_HALF_DIGIT_BIT) * (b >> MP_HALF_DIGIT_BIT); \3913a0b1 = (a & MP_HALF_DIGIT_MAX) * (b >> MP_HALF_DIGIT_BIT); \3914a1b0 = (a >> MP_HALF_DIGIT_BIT) * (b & MP_HALF_DIGIT_MAX); \3915a1b0 += a0b1; \3916Phi += a1b0 >> MP_HALF_DIGIT_BIT; \3917if (a1b0 < a0b1) \3918Phi += MP_HALF_RADIX; \3919a1b0 <<= MP_HALF_DIGIT_BIT; \3920Plo += a1b0; \3921if (Plo < a1b0) \3922++Phi; \3923}3924#endif39253926#if !defined(MP_ASSEMBLY_MULTIPLY)3927/* c = a * b */3928void s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)3929{3930#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)3931mp_digit d = 0;39323933/* Inner product: Digits of a */3934while (a_len--) {3935mp_word w = ((mp_word)b * *a++) + d;3936*c++ = ACCUM(w);3937d = CARRYOUT(w);3938}3939*c = d;3940#else3941mp_digit carry = 0;3942while (a_len--) {3943mp_digit a_i = *a++;3944mp_digit a0b0, a1b1;39453946MP_MUL_DxD(a_i, b, a1b1, a0b0);39473948a0b0 += carry;3949if (a0b0 < carry)3950++a1b1;3951*c++ = a0b0;3952carry = a1b1;3953}3954*c = carry;3955#endif3956}39573958/* c += a * b */3959void s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b,3960mp_digit *c)3961{3962#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)3963mp_digit d = 0;39643965/* Inner product: Digits of a */3966while (a_len--) {3967mp_word w = ((mp_word)b * *a++) + *c + d;3968*c++ = ACCUM(w);3969d = CARRYOUT(w);3970}3971*c = d;3972#else3973mp_digit carry = 0;3974while (a_len--) {3975mp_digit a_i = *a++;3976mp_digit a0b0, a1b1;39773978MP_MUL_DxD(a_i, b, a1b1, a0b0);39793980a0b0 += carry;3981if (a0b0 < carry)3982++a1b1;3983a0b0 += a_i = *c;3984if (a0b0 < a_i)3985++a1b1;3986*c++ = a0b0;3987carry = a1b1;3988}3989*c = carry;3990#endif3991}39923993/* Presently, this is only used by the Montgomery arithmetic code. */3994/* c += a * b */3995void s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)3996{3997#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)3998mp_digit d = 0;39994000/* Inner product: Digits of a */4001while (a_len--) {4002mp_word w = ((mp_word)b * *a++) + *c + d;4003*c++ = ACCUM(w);4004d = CARRYOUT(w);4005}40064007while (d) {4008mp_word w = (mp_word)*c + d;4009*c++ = ACCUM(w);4010d = CARRYOUT(w);4011}4012#else4013mp_digit carry = 0;4014while (a_len--) {4015mp_digit a_i = *a++;4016mp_digit a0b0, a1b1;40174018MP_MUL_DxD(a_i, b, a1b1, a0b0);40194020a0b0 += carry;4021if (a0b0 < carry)4022++a1b1;40234024a0b0 += a_i = *c;4025if (a0b0 < a_i)4026++a1b1;40274028*c++ = a0b0;4029carry = a1b1;4030}4031while (carry) {4032mp_digit c_i = *c;4033carry += c_i;4034*c++ = carry;4035carry = carry < c_i;4036}4037#endif4038}4039#endif40404041#if defined(MP_USE_UINT_DIGIT) && defined(MP_USE_LONG_LONG_MULTIPLY)4042/* This trick works on Sparc V8 CPUs with the Workshop compilers. */4043#define MP_SQR_D(a, Phi, Plo) \4044{ unsigned long long square = (unsigned long long)a * a; \4045Plo = (mp_digit)square; \4046Phi = (mp_digit)(square >> MP_DIGIT_BIT); }4047#elif defined(OSF1)4048#define MP_SQR_D(a, Phi, Plo) \4049{ Plo = asm ("mulq %a0, %a0, %v0", a);\4050Phi = asm ("umulh %a0, %a0, %v0", a); }4051#else4052#define MP_SQR_D(a, Phi, Plo) \4053{ mp_digit Pmid; \4054Plo = (a & MP_HALF_DIGIT_MAX) * (a & MP_HALF_DIGIT_MAX); \4055Phi = (a >> MP_HALF_DIGIT_BIT) * (a >> MP_HALF_DIGIT_BIT); \4056Pmid = (a & MP_HALF_DIGIT_MAX) * (a >> MP_HALF_DIGIT_BIT); \4057Phi += Pmid >> (MP_HALF_DIGIT_BIT - 1); \4058Pmid <<= (MP_HALF_DIGIT_BIT + 1); \4059Plo += Pmid; \4060if (Plo < Pmid) \4061++Phi; \4062}4063#endif40644065#if !defined(MP_ASSEMBLY_SQUARE)4066/* Add the squares of the digits of a to the digits of b. */4067void s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)4068{4069#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_MUL_WORD)4070mp_word w;4071mp_digit d;4072mp_size ix;40734074w = 0;4075#define ADD_SQUARE(n) \4076d = pa[n]; \4077w += (d * (mp_word)d) + ps[2*n]; \4078ps[2*n] = ACCUM(w); \4079w = (w >> DIGIT_BIT) + ps[2*n+1]; \4080ps[2*n+1] = ACCUM(w); \4081w = (w >> DIGIT_BIT)40824083for (ix = a_len; ix >= 4; ix -= 4) {4084ADD_SQUARE(0);4085ADD_SQUARE(1);4086ADD_SQUARE(2);4087ADD_SQUARE(3);4088pa += 4;4089ps += 8;4090}4091if (ix) {4092ps += 2*ix;4093pa += ix;4094switch (ix) {4095case 3: ADD_SQUARE(-3); /* FALLTHRU */4096case 2: ADD_SQUARE(-2); /* FALLTHRU */4097case 1: ADD_SQUARE(-1); /* FALLTHRU */4098case 0: break;4099}4100}4101while (w) {4102w += *ps;4103*ps++ = ACCUM(w);4104w = (w >> DIGIT_BIT);4105}4106#else4107mp_digit carry = 0;4108while (a_len--) {4109mp_digit a_i = *pa++;4110mp_digit a0a0, a1a1;41114112MP_SQR_D(a_i, a1a1, a0a0);41134114/* here a1a1 and a0a0 constitute a_i ** 2 */4115a0a0 += carry;4116if (a0a0 < carry)4117++a1a1;41184119/* now add to ps */4120a0a0 += a_i = *ps;4121if (a0a0 < a_i)4122++a1a1;4123*ps++ = a0a0;4124a1a1 += a_i = *ps;4125carry = (a1a1 < a_i);4126*ps++ = a1a1;4127}4128while (carry) {4129mp_digit s_i = *ps;4130carry += s_i;4131*ps++ = carry;4132carry = carry < s_i;4133}4134#endif4135}4136#endif41374138#if (defined(MP_NO_MP_WORD) || defined(MP_NO_DIV_WORD)) \4139&& !defined(MP_ASSEMBLY_DIV_2DX1D)4140/*4141** Divide 64-bit (Nhi,Nlo) by 32-bit divisor, which must be normalized4142** so its high bit is 1. This code is from NSPR.4143*/4144mp_err s_mpv_div_2dx1d(mp_digit Nhi, mp_digit Nlo, mp_digit divisor,4145mp_digit *qp, mp_digit *rp)4146{4147mp_digit d1, d0, q1, q0;4148mp_digit r1, r0, m;41494150d1 = divisor >> MP_HALF_DIGIT_BIT;4151d0 = divisor & MP_HALF_DIGIT_MAX;4152r1 = Nhi % d1;4153q1 = Nhi / d1;4154m = q1 * d0;4155r1 = (r1 << MP_HALF_DIGIT_BIT) | (Nlo >> MP_HALF_DIGIT_BIT);4156if (r1 < m) {4157q1--, r1 += divisor;4158if (r1 >= divisor && r1 < m) {4159q1--, r1 += divisor;4160}4161}4162r1 -= m;4163r0 = r1 % d1;4164q0 = r1 / d1;4165m = q0 * d0;4166r0 = (r0 << MP_HALF_DIGIT_BIT) | (Nlo & MP_HALF_DIGIT_MAX);4167if (r0 < m) {4168q0--, r0 += divisor;4169if (r0 >= divisor && r0 < m) {4170q0--, r0 += divisor;4171}4172}4173if (qp)4174*qp = (q1 << MP_HALF_DIGIT_BIT) | q0;4175if (rp)4176*rp = r0 - m;4177return MP_OKAY;4178}4179#endif41804181#if MP_SQUARE4182/* {{{ s_mp_sqr(a) */41834184mp_err s_mp_sqr(mp_int *a)4185{4186mp_err res;4187mp_int tmp;41884189if((res = mp_init_size(&tmp, 2 * USED(a), FLAG(a))) != MP_OKAY)4190return res;4191res = mp_sqr(a, &tmp);4192if (res == MP_OKAY) {4193s_mp_exch(&tmp, a);4194}4195mp_clear(&tmp);4196return res;4197}41984199/* }}} */4200#endif42014202/* {{{ s_mp_div(a, b) */42034204/*4205s_mp_div(a, b)42064207Compute a = a / b and b = a mod b. Assumes b > a.4208*/42094210mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */4211mp_int *div, /* i: divisor */4212mp_int *quot) /* i: 0; o: quotient */4213{4214mp_int part, t;4215#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)4216mp_word q_msd;4217#else4218mp_digit q_msd;4219#endif4220mp_err res;4221mp_digit d;4222mp_digit div_msd;4223int ix;42244225if(mp_cmp_z(div) == 0)4226return MP_RANGE;42274228/* Shortcut if divisor is power of two */4229if((ix = s_mp_ispow2(div)) >= 0) {4230MP_CHECKOK( mp_copy(rem, quot) );4231s_mp_div_2d(quot, (mp_digit)ix);4232s_mp_mod_2d(rem, (mp_digit)ix);42334234return MP_OKAY;4235}42364237DIGITS(&t) = 0;4238MP_SIGN(rem) = ZPOS;4239MP_SIGN(div) = ZPOS;42404241/* A working temporary for division */4242MP_CHECKOK( mp_init_size(&t, MP_ALLOC(rem), FLAG(rem)));42434244/* Normalize to optimize guessing */4245MP_CHECKOK( s_mp_norm(rem, div, &d) );42464247part = *rem;42484249/* Perform the division itself...woo! */4250MP_USED(quot) = MP_ALLOC(quot);42514252/* Find a partial substring of rem which is at least div */4253/* If we didn't find one, we're finished dividing */4254while (MP_USED(rem) > MP_USED(div) || s_mp_cmp(rem, div) >= 0) {4255int i;4256int unusedRem;42574258unusedRem = MP_USED(rem) - MP_USED(div);4259MP_DIGITS(&part) = MP_DIGITS(rem) + unusedRem;4260MP_ALLOC(&part) = MP_ALLOC(rem) - unusedRem;4261MP_USED(&part) = MP_USED(div);4262if (s_mp_cmp(&part, div) < 0) {4263-- unusedRem;4264#if MP_ARGCHK == 24265assert(unusedRem >= 0);4266#endif4267-- MP_DIGITS(&part);4268++ MP_USED(&part);4269++ MP_ALLOC(&part);4270}42714272/* Compute a guess for the next quotient digit */4273q_msd = MP_DIGIT(&part, MP_USED(&part) - 1);4274div_msd = MP_DIGIT(div, MP_USED(div) - 1);4275if (q_msd >= div_msd) {4276q_msd = 1;4277} else if (MP_USED(&part) > 1) {4278#if !defined(MP_NO_MP_WORD) && !defined(MP_NO_DIV_WORD)4279q_msd = (q_msd << MP_DIGIT_BIT) | MP_DIGIT(&part, MP_USED(&part) - 2);4280q_msd /= div_msd;4281if (q_msd == RADIX)4282--q_msd;4283#else4284mp_digit r;4285MP_CHECKOK( s_mpv_div_2dx1d(q_msd, MP_DIGIT(&part, MP_USED(&part) - 2),4286div_msd, &q_msd, &r) );4287#endif4288} else {4289q_msd = 0;4290}4291#if MP_ARGCHK == 24292assert(q_msd > 0); /* This case should never occur any more. */4293#endif4294if (q_msd <= 0)4295break;42964297/* See what that multiplies out to */4298mp_copy(div, &t);4299MP_CHECKOK( s_mp_mul_d(&t, (mp_digit)q_msd) );43004301/*4302If it's too big, back it off. We should not have to do this4303more than once, or, in rare cases, twice. Knuth describes a4304method by which this could be reduced to a maximum of once, but4305I didn't implement that here.4306* When using s_mpv_div_2dx1d, we may have to do this 3 times.4307*/4308for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {4309--q_msd;4310s_mp_sub(&t, div); /* t -= div */4311}4312if (i < 0) {4313res = MP_RANGE;4314goto CLEANUP;4315}43164317/* At this point, q_msd should be the right next digit */4318MP_CHECKOK( s_mp_sub(&part, &t) ); /* part -= t */4319s_mp_clamp(rem);43204321/*4322Include the digit in the quotient. We allocated enough memory4323for any quotient we could ever possibly get, so we should not4324have to check for failures here4325*/4326MP_DIGIT(quot, unusedRem) = (mp_digit)q_msd;4327}43284329/* Denormalize remainder */4330if (d) {4331s_mp_div_2d(rem, d);4332}43334334s_mp_clamp(quot);43354336CLEANUP:4337mp_clear(&t);43384339return res;43404341} /* end s_mp_div() */434243434344/* }}} */43454346/* {{{ s_mp_2expt(a, k) */43474348mp_err s_mp_2expt(mp_int *a, mp_digit k)4349{4350mp_err res;4351mp_size dig, bit;43524353dig = k / DIGIT_BIT;4354bit = k % DIGIT_BIT;43554356mp_zero(a);4357if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)4358return res;43594360DIGIT(a, dig) |= ((mp_digit)1 << bit);43614362return MP_OKAY;43634364} /* end s_mp_2expt() */43654366/* }}} */43674368/* {{{ s_mp_reduce(x, m, mu) */43694370/*4371Compute Barrett reduction, x (mod m), given a precomputed value for4372mu = b^2k / m, where b = RADIX and k = #digits(m). This should be4373faster than straight division, when many reductions by the same4374value of m are required (such as in modular exponentiation). This4375can nearly halve the time required to do modular exponentiation,4376as compared to using the full integer divide to reduce.43774378This algorithm was derived from the _Handbook of Applied4379Cryptography_ by Menezes, Oorschot and VanStone, Ch. 14,4380pp. 603-604.4381*/43824383mp_err s_mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu)4384{4385mp_int q;4386mp_err res;43874388if((res = mp_init_copy(&q, x)) != MP_OKAY)4389return res;43904391s_mp_rshd(&q, USED(m) - 1); /* q1 = x / b^(k-1) */4392s_mp_mul(&q, mu); /* q2 = q1 * mu */4393s_mp_rshd(&q, USED(m) + 1); /* q3 = q2 / b^(k+1) */43944395/* x = x mod b^(k+1), quick (no division) */4396s_mp_mod_2d(x, DIGIT_BIT * (USED(m) + 1));43974398/* q = q * m mod b^(k+1), quick (no division) */4399s_mp_mul(&q, m);4400s_mp_mod_2d(&q, DIGIT_BIT * (USED(m) + 1));44014402/* x = x - q */4403if((res = mp_sub(x, &q, x)) != MP_OKAY)4404goto CLEANUP;44054406/* If x < 0, add b^(k+1) to it */4407if(mp_cmp_z(x) < 0) {4408mp_set(&q, 1);4409if((res = s_mp_lshd(&q, USED(m) + 1)) != MP_OKAY)4410goto CLEANUP;4411if((res = mp_add(x, &q, x)) != MP_OKAY)4412goto CLEANUP;4413}44144415/* Back off if it's too big */4416while(mp_cmp(x, m) >= 0) {4417if((res = s_mp_sub(x, m)) != MP_OKAY)4418break;4419}44204421CLEANUP:4422mp_clear(&q);44234424return res;44254426} /* end s_mp_reduce() */44274428/* }}} */44294430/* }}} */44314432/* {{{ Primitive comparisons */44334434/* {{{ s_mp_cmp(a, b) */44354436/* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b */4437int s_mp_cmp(const mp_int *a, const mp_int *b)4438{4439mp_size used_a = MP_USED(a);4440{4441mp_size used_b = MP_USED(b);44424443if (used_a > used_b)4444goto IS_GT;4445if (used_a < used_b)4446goto IS_LT;4447}4448{4449mp_digit *pa, *pb;4450mp_digit da = 0, db = 0;44514452#define CMP_AB(n) if ((da = pa[n]) != (db = pb[n])) goto done44534454pa = MP_DIGITS(a) + used_a;4455pb = MP_DIGITS(b) + used_a;4456while (used_a >= 4) {4457pa -= 4;4458pb -= 4;4459used_a -= 4;4460CMP_AB(3);4461CMP_AB(2);4462CMP_AB(1);4463CMP_AB(0);4464}4465while (used_a-- > 0 && ((da = *--pa) == (db = *--pb)))4466/* do nothing */;4467done:4468if (da > db)4469goto IS_GT;4470if (da < db)4471goto IS_LT;4472}4473return MP_EQ;4474IS_LT:4475return MP_LT;4476IS_GT:4477return MP_GT;4478} /* end s_mp_cmp() */44794480/* }}} */44814482/* {{{ s_mp_cmp_d(a, d) */44834484/* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d */4485int s_mp_cmp_d(const mp_int *a, mp_digit d)4486{4487if(USED(a) > 1)4488return MP_GT;44894490if(DIGIT(a, 0) < d)4491return MP_LT;4492else if(DIGIT(a, 0) > d)4493return MP_GT;4494else4495return MP_EQ;44964497} /* end s_mp_cmp_d() */44984499/* }}} */45004501/* {{{ s_mp_ispow2(v) */45024503/*4504Returns -1 if the value is not a power of two; otherwise, it returns4505k such that v = 2^k, i.e. lg(v).4506*/4507int s_mp_ispow2(const mp_int *v)4508{4509mp_digit d;4510int extra = 0, ix;45114512ix = MP_USED(v) - 1;4513d = MP_DIGIT(v, ix); /* most significant digit of v */45144515extra = s_mp_ispow2d(d);4516if (extra < 0 || ix == 0)4517return extra;45184519while (--ix >= 0) {4520if (DIGIT(v, ix) != 0)4521return -1; /* not a power of two */4522extra += MP_DIGIT_BIT;4523}45244525return extra;45264527} /* end s_mp_ispow2() */45284529/* }}} */45304531/* {{{ s_mp_ispow2d(d) */45324533int s_mp_ispow2d(mp_digit d)4534{4535if ((d != 0) && ((d & (d-1)) == 0)) { /* d is a power of 2 */4536int pow = 0;4537#if defined (MP_USE_UINT_DIGIT)4538if (d & 0xffff0000U)4539pow += 16;4540if (d & 0xff00ff00U)4541pow += 8;4542if (d & 0xf0f0f0f0U)4543pow += 4;4544if (d & 0xccccccccU)4545pow += 2;4546if (d & 0xaaaaaaaaU)4547pow += 1;4548#elif defined(MP_USE_LONG_LONG_DIGIT)4549if (d & 0xffffffff00000000ULL)4550pow += 32;4551if (d & 0xffff0000ffff0000ULL)4552pow += 16;4553if (d & 0xff00ff00ff00ff00ULL)4554pow += 8;4555if (d & 0xf0f0f0f0f0f0f0f0ULL)4556pow += 4;4557if (d & 0xccccccccccccccccULL)4558pow += 2;4559if (d & 0xaaaaaaaaaaaaaaaaULL)4560pow += 1;4561#elif defined(MP_USE_LONG_DIGIT)4562if (d & 0xffffffff00000000UL)4563pow += 32;4564if (d & 0xffff0000ffff0000UL)4565pow += 16;4566if (d & 0xff00ff00ff00ff00UL)4567pow += 8;4568if (d & 0xf0f0f0f0f0f0f0f0UL)4569pow += 4;4570if (d & 0xccccccccccccccccUL)4571pow += 2;4572if (d & 0xaaaaaaaaaaaaaaaaUL)4573pow += 1;4574#else4575#error "unknown type for mp_digit"4576#endif4577return pow;4578}4579return -1;45804581} /* end s_mp_ispow2d() */45824583/* }}} */45844585/* }}} */45864587/* {{{ Primitive I/O helpers */45884589/* {{{ s_mp_tovalue(ch, r) */45904591/*4592Convert the given character to its digit value, in the given radix.4593If the given character is not understood in the given radix, -1 is4594returned. Otherwise the digit's numeric value is returned.45954596The results will be odd if you use a radix < 2 or > 62, you are4597expected to know what you're up to.4598*/4599int s_mp_tovalue(char ch, int r)4600{4601int val, xch;46024603if(r > 36)4604xch = ch;4605else4606xch = toupper(ch);46074608if(isdigit(xch))4609val = xch - '0';4610else if(isupper(xch))4611val = xch - 'A' + 10;4612else if(islower(xch))4613val = xch - 'a' + 36;4614else if(xch == '+')4615val = 62;4616else if(xch == '/')4617val = 63;4618else4619return -1;46204621if(val < 0 || val >= r)4622return -1;46234624return val;46254626} /* end s_mp_tovalue() */46274628/* }}} */46294630/* {{{ s_mp_todigit(val, r, low) */46314632/*4633Convert val to a radix-r digit, if possible. If val is out of range4634for r, returns zero. Otherwise, returns an ASCII character denoting4635the value in the given radix.46364637The results may be odd if you use a radix < 2 or > 64, you are4638expected to know what you're doing.4639*/46404641char s_mp_todigit(mp_digit val, int r, int low)4642{4643char ch;46444645if(val >= (unsigned int)r)4646return 0;46474648ch = s_dmap_1[val];46494650if(r <= 36 && low)4651ch = tolower(ch);46524653return ch;46544655} /* end s_mp_todigit() */46564657/* }}} */46584659/* {{{ s_mp_outlen(bits, radix) */46604661/*4662Return an estimate for how long a string is needed to hold a radix4663r representation of a number with 'bits' significant bits, plus an4664extra for a zero terminator (assuming C style strings here)4665*/4666int s_mp_outlen(int bits, int r)4667{4668return (int)((double)bits * LOG_V_2(r) + 1.5) + 1;46694670} /* end s_mp_outlen() */46714672/* }}} */46734674/* }}} */46754676/* {{{ mp_read_unsigned_octets(mp, str, len) */4677/* mp_read_unsigned_octets(mp, str, len)4678Read in a raw value (base 256) into the given mp_int4679No sign bit, number is positive. Leading zeros ignored.4680*/46814682mp_err4683mp_read_unsigned_octets(mp_int *mp, const unsigned char *str, mp_size len)4684{4685int count;4686mp_err res;4687mp_digit d;46884689ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);46904691mp_zero(mp);46924693count = len % sizeof(mp_digit);4694if (count) {4695for (d = 0; count-- > 0; --len) {4696d = (d << 8) | *str++;4697}4698MP_DIGIT(mp, 0) = d;4699}47004701/* Read the rest of the digits */4702for(; len > 0; len -= sizeof(mp_digit)) {4703for (d = 0, count = sizeof(mp_digit); count > 0; --count) {4704d = (d << 8) | *str++;4705}4706if (MP_EQ == mp_cmp_z(mp)) {4707if (!d)4708continue;4709} else {4710if((res = s_mp_lshd(mp, 1)) != MP_OKAY)4711return res;4712}4713MP_DIGIT(mp, 0) = d;4714}4715return MP_OKAY;4716} /* end mp_read_unsigned_octets() */4717/* }}} */47184719/* {{{ mp_unsigned_octet_size(mp) */4720int4721mp_unsigned_octet_size(const mp_int *mp)4722{4723int bytes;4724int ix;4725mp_digit d = 0;47264727ARGCHK(mp != NULL, MP_BADARG);4728ARGCHK(MP_ZPOS == SIGN(mp), MP_BADARG);47294730bytes = (USED(mp) * sizeof(mp_digit));47314732/* subtract leading zeros. */4733/* Iterate over each digit... */4734for(ix = USED(mp) - 1; ix >= 0; ix--) {4735d = DIGIT(mp, ix);4736if (d)4737break;4738bytes -= sizeof(d);4739}4740if (!bytes)4741return 1;47424743/* Have MSD, check digit bytes, high order first */4744for(ix = sizeof(mp_digit) - 1; ix >= 0; ix--) {4745unsigned char x = (unsigned char)(d >> (ix * CHAR_BIT));4746if (x)4747break;4748--bytes;4749}4750return bytes;4751} /* end mp_unsigned_octet_size() */4752/* }}} */47534754/* {{{ mp_to_unsigned_octets(mp, str) */4755/* output a buffer of big endian octets no longer than specified. */4756mp_err4757mp_to_unsigned_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)4758{4759int ix, pos = 0;4760unsigned int bytes;47614762ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);47634764bytes = mp_unsigned_octet_size(mp);4765ARGCHK(bytes <= maxlen, MP_BADARG);47664767/* Iterate over each digit... */4768for(ix = USED(mp) - 1; ix >= 0; ix--) {4769mp_digit d = DIGIT(mp, ix);4770int jx;47714772/* Unpack digit bytes, high order first */4773for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {4774unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));4775if (!pos && !x) /* suppress leading zeros */4776continue;4777str[pos++] = x;4778}4779}4780if (!pos)4781str[pos++] = 0;4782return pos;4783} /* end mp_to_unsigned_octets() */4784/* }}} */47854786/* {{{ mp_to_signed_octets(mp, str) */4787/* output a buffer of big endian octets no longer than specified. */4788mp_err4789mp_to_signed_octets(const mp_int *mp, unsigned char *str, mp_size maxlen)4790{4791int ix, pos = 0;4792unsigned int bytes;47934794ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);47954796bytes = mp_unsigned_octet_size(mp);4797ARGCHK(bytes <= maxlen, MP_BADARG);47984799/* Iterate over each digit... */4800for(ix = USED(mp) - 1; ix >= 0; ix--) {4801mp_digit d = DIGIT(mp, ix);4802int jx;48034804/* Unpack digit bytes, high order first */4805for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {4806unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));4807if (!pos) {4808if (!x) /* suppress leading zeros */4809continue;4810if (x & 0x80) { /* add one leading zero to make output positive. */4811ARGCHK(bytes + 1 <= maxlen, MP_BADARG);4812if (bytes + 1 > maxlen)4813return MP_BADARG;4814str[pos++] = 0;4815}4816}4817str[pos++] = x;4818}4819}4820if (!pos)4821str[pos++] = 0;4822return pos;4823} /* end mp_to_signed_octets() */4824/* }}} */48254826/* {{{ mp_to_fixlen_octets(mp, str) */4827/* output a buffer of big endian octets exactly as long as requested. */4828mp_err4829mp_to_fixlen_octets(const mp_int *mp, unsigned char *str, mp_size length)4830{4831int ix, pos = 0;4832unsigned int bytes;48334834ARGCHK(mp != NULL && str != NULL && !SIGN(mp), MP_BADARG);48354836bytes = mp_unsigned_octet_size(mp);4837ARGCHK(bytes <= length, MP_BADARG);48384839/* place any needed leading zeros */4840for (;length > bytes; --length) {4841*str++ = 0;4842}48434844/* Iterate over each digit... */4845for(ix = USED(mp) - 1; ix >= 0; ix--) {4846mp_digit d = DIGIT(mp, ix);4847int jx;48484849/* Unpack digit bytes, high order first */4850for(jx = sizeof(mp_digit) - 1; jx >= 0; jx--) {4851unsigned char x = (unsigned char)(d >> (jx * CHAR_BIT));4852if (!pos && !x) /* suppress leading zeros */4853continue;4854str[pos++] = x;4855}4856}4857if (!pos)4858str[pos++] = 0;4859return MP_OKAY;4860} /* end mp_to_fixlen_octets() */4861/* }}} */486248634864/*------------------------------------------------------------------------*/4865/* HERE THERE BE DRAGONS */486648674868