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