Home | History | Annotate | Line # | Download | only in generic
      1  1.1  mrg /* mpn_cnd_add_n -- Compute R = U + V if CND != 0 or R = U if CND == 0.
      2  1.1  mrg    Both cases should take the same time and perform the exact same memory
      3  1.1  mrg    accesses, since this function is intended to be used where side-channel
      4  1.1  mrg    attack resilience is relevant.
      5  1.1  mrg 
      6  1.1  mrg Copyright 1992-1994, 1996, 2000, 2002, 2008, 2009, 2011, 2013 Free Software
      7  1.1  mrg Foundation, Inc.
      8  1.1  mrg 
      9  1.1  mrg This file is part of the GNU MP Library.
     10  1.1  mrg 
     11  1.1  mrg The GNU MP Library is free software; you can redistribute it and/or modify
     12  1.1  mrg it under the terms of either:
     13  1.1  mrg 
     14  1.1  mrg   * the GNU Lesser General Public License as published by the Free
     15  1.1  mrg     Software Foundation; either version 3 of the License, or (at your
     16  1.1  mrg     option) any later version.
     17  1.1  mrg 
     18  1.1  mrg or
     19  1.1  mrg 
     20  1.1  mrg   * the GNU General Public License as published by the Free Software
     21  1.1  mrg     Foundation; either version 2 of the License, or (at your option) any
     22  1.1  mrg     later version.
     23  1.1  mrg 
     24  1.1  mrg or both in parallel, as here.
     25  1.1  mrg 
     26  1.1  mrg The GNU MP Library is distributed in the hope that it will be useful, but
     27  1.1  mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     28  1.1  mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     29  1.1  mrg for more details.
     30  1.1  mrg 
     31  1.1  mrg You should have received copies of the GNU General Public License and the
     32  1.1  mrg GNU Lesser General Public License along with the GNU MP Library.  If not,
     33  1.1  mrg see https://www.gnu.org/licenses/.  */
     34  1.1  mrg 
     35  1.1  mrg #include "gmp-impl.h"
     36  1.1  mrg 
     37  1.1  mrg mp_limb_t
     38  1.1  mrg mpn_cnd_add_n (mp_limb_t cnd, mp_ptr rp, mp_srcptr up, mp_srcptr vp, mp_size_t n)
     39  1.1  mrg {
     40  1.1  mrg   mp_limb_t ul, vl, sl, rl, cy, cy1, cy2, mask;
     41  1.1  mrg 
     42  1.1  mrg   ASSERT (n >= 1);
     43  1.1  mrg   ASSERT (MPN_SAME_OR_SEPARATE_P (rp, up, n));
     44  1.1  mrg   ASSERT (MPN_SAME_OR_SEPARATE_P (rp, vp, n));
     45  1.1  mrg 
     46  1.1  mrg   mask = -(mp_limb_t) (cnd != 0);
     47  1.1  mrg   cy = 0;
     48  1.1  mrg   do
     49  1.1  mrg     {
     50  1.1  mrg       ul = *up++;
     51  1.1  mrg       vl = *vp++ & mask;
     52  1.1  mrg #if GMP_NAIL_BITS == 0
     53  1.1  mrg       sl = ul + vl;
     54  1.1  mrg       cy1 = sl < ul;
     55  1.1  mrg       rl = sl + cy;
     56  1.1  mrg       cy2 = rl < sl;
     57  1.1  mrg       cy = cy1 | cy2;
     58  1.1  mrg       *rp++ = rl;
     59  1.1  mrg #else
     60  1.1  mrg       rl = ul + vl;
     61  1.1  mrg       rl += cy;
     62  1.1  mrg       cy = rl >> GMP_NUMB_BITS;
     63  1.1  mrg       *rp++ = rl & GMP_NUMB_MASK;
     64  1.1  mrg #endif
     65  1.1  mrg     }
     66  1.1  mrg   while (--n != 0);
     67  1.1  mrg 
     68  1.1  mrg   return cy;
     69  1.1  mrg }
     70